日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言修改字符串c2133,通过create_string_buffer、create_unicode_buffer让C语言具备修改字符串的能力...

發布時間:2025/3/12 编程问答 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言修改字符串c2133,通过create_string_buffer、create_unicode_buffer让C语言具备修改字符串的能力... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字符串的修改

我們知道C中不存在字符串這個概念,python中的字符串在C中也是通過字符數組來實現的。我們說在C中創建一個字符數組有兩種方式:

char *s1 = "hello world";

char s2[] = "hello world";

這兩種方式雖然打印的結果是一樣的,并且s1、s2都指向了對應字符數組的首地址,但是內部的結構確是不同的。

1.char *s1 = "hello world";此時這個字符數組是存放在靜態存儲區里面的,程序編譯的時候這塊區域就已經確定好了,靜態存儲區在程序的整個運行期間都是存在的,主要用來存放一些靜態變量、全局變量、常量。因此s1只能夠訪問這個字符數組,卻不能夠改變它,因為它是一個常量。而char s2[] = "hello world";,這種方式創建的字符數組是存放在棧當中的,可以通過s2這個指針去修改它。

2.char *s1 = "hello world";是在編譯的時候就已經確定了,因為是一個常量。而char s2[] = "hello world";則是在運行時才確定。

3.char *s1 = "hello world";創建的字符數組存于靜態存儲區,char s2[] = "hello world";創建的字符數組存儲于棧區,所以s1訪問的速度沒有s2快。

所以我們說char?*s這種方式創建的字符數組在C中是不能修改的,但是我們通過ctypes卻可以做到對char?*s進行修改:

#include

int test(char *s1, char s2[6])

{

//兩種方式都進行修改

s1[0] = 'a';

s2[0] = 'a';

printf("s1 = %s, s2 = %s\n", s1, s2);

}

我們還是將C文件編譯成mmp.dll

import ctypes

from ctypes import *

lib = ctypes.CDLL("./mmp.dll")

# 我們看到無論是char *s1,還是char s2[...],我們都可以使用c_char_p這種方式傳遞

lib.test(c_char_p(b"hello"), c_char_p(b"hello")) # s1 = aello, s2 = aello

我們看到兩種方式都成功修改了,但是即便能修改,我們不建議這么做。不是說不讓修改,而是應該換一種方式。如果是需要修改的話,那么不要使用c_char_p的方式來傳遞,而是建議通過create_string_buffer來給C語言傳遞可以修改字符的空間。

create_string_buffer

create_string_buffer是ctypes提供的一個函數,表示創建具有一定大小的字符緩存,就理解為字符數組即可。

from ctypes import *

# 傳入一個int,表示創建一個具有固定大小的字符緩存,這里是10個

s = create_string_buffer(10)

# 直接打印就是一個對象

print(s) #

# 也可以調用value方法打印它的值,可以看到什么都沒有

print(s.value) # b''

# 并且它還有一個raw方法,表示C語言中的字符數組,由于長度為10,并且沒有內容,所以全部是\x00,就是C語言中的\0

print(s.raw) # b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

# 還可以查看長度

print(len(s)) # 10

當然create_string_buffer如果只傳一個int,那么表示創建對應長度的字符緩存。除此之外,還可以指定字節串,此時的字符緩存大小和指定的字節串大小是一致的:

from ctypes import *

# 此時我們直接創建了一個字符緩存

s = create_string_buffer(b"hello")

print(s) #

print(s.value) # b'hello'

# 我們知道在C中,字符數組是以\0作為結束標記的,所以結尾會有一個\0,因為raw表示C中的字符數組

print(s.raw) # b'hello\x00'

# 長度為6,b"hello"五個字符再加上\0一共6個

print(len(s))

當然create_string_buffer還可以指定字節串的同時,指定空間大小。

from ctypes import *

# 此時我們直接創建了一個字符緩存,如果不指定容量,那么默認和對應的字符數組大小一致

# 但是我們還可以同時指定容量,記得容量要比前面的字節串的長度要大。

s = create_string_buffer(b"hello", 10)

print(s) #

print(s.value) # b'hello'

# 長度為10,剩余的5個顯然是\0

print(s.raw) # b'hello\x00\x00\x00\x00\x00'

print(len(s)) # 10

下面我們來看看如何使用create_string_buffer來傳遞:

#include

int test(char *s)

{

//變量的形式依舊是char *s

//下面的操作就是相當于把字符數組的索引為5到11的部分換成" satori"

s[5] = ' ';

s[6] = 's';

s[7] = 'a';

s[8] = 't';

s[9] = 'o';

s[10] = 'r';

s[11] = 'i';

printf("s = %s\n", s);

}

from ctypes import *

lib = CDLL("./mmp.dll")

s = create_string_buffer(b"hello", 20)

lib.test(s) # s = hello satori

此時就成功地修改了,我們這里的b"hello"占五個字節,下一個正好是索引為5的地方,然后把索引為5到11的部分換成對應的字符。但是需要注意的是,一定要小心\0,我們知道C語言中一旦遇到了\0就表示這個字符數組結束了。

from ctypes import *

lib = CDLL("./mmp.dll")

# 這里把"hello"換成"hell",看看會發生什么

s = create_string_buffer(b"hell", 20)

lib.test(s) # s = hell

# 我們看到這里只打印了"hell",這是為什么?

# 我們看一下這個s

print(s.raw) # b'hell\x00 satori\x00\x00\x00\x00\x00\x00\x00\x00'

# 我們看到這個create_string_buffer返回的對象是可變的,在將s傳進去之后被修改了

# 如果沒有傳遞的話,我們知道它是長這樣的。

"""

b'hell\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

hell的后面全部是C語言中的\0

修改之后變成了這樣

b'hell\x00 satori\x00\x00\x00\x00\x00\x00\x00\x00'

我們看到確實是把索引為5到11(包含11)的部分變成了"satori"

但是我們知道C語言中掃描字符數組的時候一旦遇到了\0,就表示結束了,而hell后面就是\0,

因為即便后面還有內容也不會輸出了,所以直接就只打印了hell

"""

另外除了create_string_buffer之外,還有一個create_unicode_buffer,針對于wchar_t,用法和create_string_buffer一樣。

C語言中查看字符數組的長度

C語言中如何查看字符數組的長度呢?有兩種方法,一種是通過sizeof,一種是通過strlen。話說我說這個干什么?算了,不管了。

#include

#include

int main() {

char s[] = "hello world";

//C語言中查看字符串的長度可以使用strlen,這個需要導入string.h頭文件。strlen計算的就是字符的個數,不包括\0

//使用sizeof計算的結果是包含\0的,所以會比strlen計算的結果多1

printf("%d %d\n", strlen(s), sizeof(s) / sizeof(s[0])); // 11 12

return 0;

}

但是我們發現字符數組的創建方式是通過char s[]這種形式,如果是char?*s呢?

#include

#include

int main() {

char *s = "hello world";

printf("%d %d\n", strlen(s), sizeof(s) / sizeof(s[0])); // 11 8

return 0;

}

我們看到使用strlen計算的結果是一樣的,但是使用sizeof得到的結果卻是不一樣的。因為char?*s,這個s我們雖然可以使用它來打印字符數組,但它本質上是一個指針,一個指針在64位機器上占8個字節,所以結果是8。而char?s[]中的s雖然也指向字符數組的首地址,但它本質上是一個數組名,我們使用sizeof查看得到的結果還是字符數組中所有元素的總大小。

艾瑪,你扯到C上面干啥。。。。。。你又不會C。。。。。。

來源:https://www.cnblogs.com/traditional/p/12238984.html

總結

以上是生活随笔為你收集整理的c语言修改字符串c2133,通过create_string_buffer、create_unicode_buffer让C语言具备修改字符串的能力...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。