我看不到为什么我会从此代码中得到细分故障,而当我使用数组而不是指针时,它可以工作,如果有人能让我理解这一点,我会很高兴。
void main() {
char *str = "example string";
wrapChrInStr(str, 'a');
}
void wrapChrInStr(char *str, unsigned char chr) {
char *ptr = str;
char c;
while((c = *ptr)) {
if(c != chr) {
*str = c;
str++;
ptr++;
} else {
ptr++;
}
}
*str = ' ';
}
谢谢。我正在做很多C编程,这真的很奇怪,我以前从未面对过。
可能是因为您没有意识到存储有不同的方法C弦。您可能很幸运从未遇到过segfault因此。
字符串文字
用双引号标记声明了字符串字面的字符串,例如
"hello world"
此字符串通常存储在只读部分中。使用字符串时文字,最好用这样的const
声明变量:
const char *str = "hello world";
使用此您知道str
指向只读内存位置,而您不能操纵字符串的内容。实际上,如果您这样做:
const char *str = "hello world";
str[0] = 'H';
// or the equivalent
*str = 'H'
编译器将返回这样的错误:
a.c:5:5: error: assignment of read-only location ‘*str’
我发现这很有帮助,因为您不能意外操纵str
指向的内容。
数组
如果您需要操纵字符串的内容,则需要存储阵列中的字符串,例如
char str[] = "hello word";
在这种情况下,编译器知道字符串具有10个字符,并保留11个字节(1个字节' '
-终端字节),用于str
,并使用使用字符串文字的内容。
在这里您可以做
之类的事情str[0] = 'H'
但是您无法访问第11个字节。
您还可以声明具有固定尺寸的数组。在这种情况下,大小必须是至少与字符串的长度 1相同。
char str[11] = "Hello world";
如果您声明更少的空间(例如char str[3] = "hello world";
),您的编译器会警告您这样的东西
a.c:4:14: warning: initializer-string for array of chars is too long
,但是我不确定如果您执行代码会发生什么。我认为这是一个不确定的行为的情况这意味着:任何事情都可能发生。
就个人而言,我通常会声明我的字符串,没有固定尺寸,除非有固定尺寸的原因。