void trim(char *line)
{
int i = 0;
char new_line[strlen(line)];
char *start_line = line;
while (*line != '\0')
{
if (*line != ' ' && *line != '\t')
{
new_line[i] = *line;
i++;
}
line++;
}
new_line[i] = '\0';
printf("%s\n", start_line);
printf("%s\n", new_line);
strcpy(start_line, new_line);
}
我真的找不到这里的问题。我的指针已初始化,我制作了一个指针以开始字符串行。最后我想在旧行中复制新行,这样调用者的行值就会改变。
但是 strcpy() 会产生段错误。怎么了?
这是调用 trim() 的代码:
char *str = "Irish People Try American Food";
printf("%s\n", str);
trim(str);
printf("%s\n", str);
最佳答案
你需要展示整个程序;什么叫做“修剪()”? Paul R 的回答是正确的,你少了一个字符,至少应该是:
char new_line[strlen(line) + 1];
但是,这并不总是会导致段错误,如果发生了,它可能不会在 strcpy()
处。
strcpy(start_line, new_line)
出错的可能原因是 start_line 指向 line
的原始值。很可能您正在调用该函数:
int main() {
trim("blah blah\tblah");
return 0;
}
如果是这样,line
是指向无法修改的常量 字符数组的指针。在许多操作系统上,它存储在只读内存区域中,因此如果进行写入尝试,它将立即导致段错误。因此 strcpy()
在尝试写入此只读位置时会出错。
作为快速测试试试这个:
int main() {
char test[100] = "blah blah\tblah";
trim(test);
return 0;
}
如果它有效,那就是你的 strcpy() 错误的具体问题。
编辑 - 后来更新了问题以包含 main() 调用函数,该函数确认 trim 函数是使用指向字符串常量的指针调用的。问题行是:
char *str = "Irish People Try American Food";
这将创建一个字符串文字,一个包含 31 个字符的数组,其中包括一个无法修改的空终止符。然后使用此常量 数组的地址初始化指针 str
。
更正的方法是分配一个规则的字符数组,然后用已知的字符串初始化它。在这种情况下,分配和临时常量字符串文字可能会也可能不会被优化掉,但最终结果总是相同的——一个用所需文本初始化的可写字符数组:
char str[100] = "Irish People Try American Food";
/* or */
char str2[] = "American People Like Irish Beer";
/* or */
char *str3[37];
strcpy(str3, "And German Beer"); /* example only, need to check length */
这些创建长度分别为 100、32 和 37 的普通可写字符数组。然后使用给定的字符串对每个进行初始化。
ANSI/ISO C 标准定义了这样一种语言,即字符串文字是一个char
不能修改 的数组。即使它最初是在 C89 中标准化的,情况也是如此。在此之前,字符串文字通常是可写的,例如在非常早期的 UNIX 代码的准标准 K&R C 中。
Identical string literals of either form need not be distinct. If the program attempts to modify a string literal of either form, the behavior is undefined. - ANSI X3.159-1989
从那时起,许多 C89 和更新的编译器将此数组放入 .text 或 .rodata 段中,在这些段中它甚至可能在物理上不可写(ROM、只读 MMU 页面等),如此处发现。编译器也可能将重复的字符串常量合并为一个以节省空间——您也不会写入其中的“一个”!
事实上,这些语义上不可写的字符串仍然保留为 char *
类型,并且可以这样分配和传递它们,这被认为是一种妥协,即使 C89 标准正在制定中起草的。他们没有使用当时全新的类型限定符 const
被描述为“不完全满意的结果”。参见 Richie's (DMR's)解释。
很显然,近 30 年后,这个结果仍然回旋镖,让人们大吃一惊。
关于c - strcpy 的段错误,即使指针有指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35872024/