我试图将一个字符串作为参数传递给一个函数,但它抛出了一个分段错误(核心转储)错误。你能告诉我我在这里犯了什么错误吗?代码如下:
replaceChars(char str[], char sChar[], char rChar)
{
int i,j;
printf("rChar is %c", rChar);
printf("sChar is %s", sChar);
for(i = 0; i <= strlen(str); i++)
{
for(j = 0; j <= strlen(sChar); j++)
{
if(str[i] == sChar[j])
{
str[i] = rChar;
//printf("The New String is %c", str[i]);
}
}
}
printf("The New String is %s", str);
}
void main()
{
char myString[36], schar[36], rchar;
printf("Please enter a string:");
scanf("%[^\n]s", &myString);
printf("Which characters to replace?");
scanf(" %[^\n]c", &schar);
printf("With which character?");
scanf(" %[^\n]c", &rchar);
replaceChars(myString, schar, rchar);
}发布于 2018-10-04 04:30:27
这里有两个问题。
首先,当您遍历str和sChar时
我试图将一个字符串作为参数传递给一个函数,但它抛出了一个分段错误(核心转储)错误。你能告诉我我在这里犯了什么错误吗?代码如下:
for(i = 0; i <= strlen(str); i++)
{
for(j = 0; j <= strlen(sChar); j++)
{您使用<=作为退出条件。数组索引从0开始,因此有效的索引是从0到长度-1。您将从0到长度,因此您将步进数组的末尾。读取超过数组末尾的内容将调用undefined behavior。
更改条件以使用<
for(i = 0; i < strlen(str); i++)
{
for(j = 0; j < strlen(sChar); j++)
{第二个问题是如何读取值:
scanf("%[^\n]s", &myString);
...
scanf(" %[^\n]c", &schar);
...
scanf(" %[^\n]c", &rchar);%[]格式说明符后面不需要任何字符,它需要char *作为参数,该参数指向char数组的第一个元素。在第三种情况下,当格式需要指向多个字符的指针时,您将传递指向单个char的指针。因为您希望读取单个字符,所以需要改用%c格式说明符。
scanf("%35[^\n]", myString);
...
scanf(" %35[^\n]", schar);
...
scanf(" %c", &rchar);还要注意的是,前两个函数的字段宽度限制了读取的字符数,这样就不会使数组溢出。
发布于 2018-10-04 05:43:13
,你能告诉我我在这里犯了什么错误吗?
除了@dbush的好答案之外,OP的代码也是不必要的低效的。
使用下面更正后的代码,并分别假设str, sChar的初始长度为S,C。
for(i = 0; i < strlen(str); i++) {
for(j = 0; j < strlen(sChar); j++) {
if(str[i] == sChar[j]) {
str[i] = rChar;
}
}
}for(i = 0; i < strlen(str); i++) {和后面的str[i] = rChar;要求代码找到str长度的S倍,并且每个strlen(str)都需要O(S)操作。
如果S是一个非常重要的值,比如1000,那么这个1000*1000很容易影响整体性能。一种简单的解决方案是计算一次长度,或者改为查找空字符。
// for(i = 0; i < strlen(str); i++) {
S = strlen(str);
for(i = 0; i < S; i++) {
// or
for(i = 0; str[i]; i++) {同样的事情也发生在内部循环上。然而,聪明的编译器可以看到sChar没有变化,并且可以利用理解strlen()没有副作用的优势,这可能会导致不同的结果。通过这样的优化,strlen(sChar)可以真正调用一次,即使strlen(sChar)在更高的for (i...)循环中也是如此。
尽管如此,只测试空字符还是很容易的。
// for(j = 0; j < strlen(sChar); j++)
// better as
for(j = 0; sChar[j]; j++)然而,为什么这不适用于for(i = 0; i < strlen(str); i++)循环呢?
在该循环中,代码可以修改str[],因此编译器不能像使用for(j = 0; sChar[j]; j++)那样进行优化。
这也回避了一个问题,如果替换字符rChar是空字符,代码应该怎么做?
在我看来,代码要么继续,多次用'\0替换,要么在第一次之后简单地返回。
str[i] = rChar;
if (rChar == '\0') return; // Possible way to handle \0https://stackoverflow.com/questions/52634855
复制相似问题