简体   繁体   English

将字符数组作为函数参数传递

[英]Passing an array of characters as function arguments

I am trying to pass a string as an argument to a function and it throws a Segmentation fault(Core Dumped) error. 我正在尝试将字符串作为参数传递给函数,它引发了Segmentation Fault(Core Dumped)错误。 Could you please let me know what mistake I am making here? 您能告诉我我在这里犯了什么错误吗? Here is the code: 这是代码:

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);

}

Two issues here. 这里有两个问题。

First, when you loop through str and sChar : 首先,当您遍历strsChar

I am trying to pass a string as an argument to a function and it throws a Segmentation fault(Core Dumped) error. 我正在尝试将字符串作为参数传递给函数,它引发了Segmentation Fault(Core Dumped)错误。 Could you please let me know what mistake I am making here? 您能告诉我我在这里犯了什么错误吗? Here is the code: 这是代码:

for(i = 0; i <= strlen(str); i++)
{
    for(j = 0; j <= strlen(sChar); j++)
    {

You use <= as your exit condition. 您使用<=作为退出条件。 Array indexes start from 0, so valid indexes are from 0 to length-1. 数组索引从0开始,因此有效索引从0到length-1。 You're going from 0 to length, so you're stepping of the end of the array. 您要从0到长度,所以要步进数组的末尾。 Reading past the end of an array invokes undefined behavior . 读取数组末尾会调用未定义的行为

Change the conditions to use < : 更改条件以使用<

for(i = 0; i < strlen(str); i++)
{
    for(j = 0; j < strlen(sChar); j++)
    {

The second problem is in how you're reading the values: 第二个问题是如何读取值:

scanf("%[^\n]s", &myString);
...
scanf(" %[^\n]c", &schar);
...
scanf(" %[^\n]c", &rchar);

The %[] format specifier doesn't require any characters after it, and it requires a char * as a parameter which points to the first element of an array of char . %[]格式说明符后面不需要任何字符,并且需要char *作为参数,它指向char数组的第一个元素。 In the first two cases, you're passing the address of an array instead of the array itself (which decays to a pointer) and you have an extra character after the %[] format that isn't needed. 在前两种情况下,您传递的是数组的地址,而不是数组本身(它会衰减为指针),并且在%[]格式之后有多余的字符。 In the third case you pass a pointer to a single char when a pointer to multiple characters is expected by the format. 在第三种情况下,如果格式需要指向多个字符的指针,则将指针传递给单个char Because you want to read a single char, you want to use the %c format specifier instead. 因为您要读取一个字符,所以您想使用%c格式说明符。

scanf("%35[^\n]", myString);
...
scanf(" %35[^\n]", schar);
...
scanf(" %c", &rchar);

Note also that the first two have a field width that limits the number of characters that are read so that you don't overrun the arrays. 还要注意,前两个字段的宽度限制了读取的字符数,因此您不会溢出数组。

Could you please let me know what mistake I am making here? 您能告诉我我在这里犯了什么错误吗?

In addition to @dbush good answer, OP's code is unnecessarily inefficient. 除了@dbush好的答案外,OP的代码不必要地效率低下。

Using the corrected code below, and assume the initial length of the str, sChar are S,C respectively. 使用下面的更正代码,并假定str, sChar的初始长度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;
    }
  }
}

The for(i = 0; i < strlen(str); i++) { and with the later str[i] = rChar; for(i = 0; i < strlen(str); i++) {并且后面的str[i] = rChar; obliges the code to find the length of str up to S times and each strlen(str) requires O(S) operations. 强制代码查找最长为S倍的str的长度,并且每个strlen(str)需要O(S)操作。

If S was a non-trivial value, say 1000, this 1000*1000 could readily affect overall performance. 如果S是一个非平凡的值,例如1000,则此1000 * 1000可能会轻易影响整体性能。 A simply solution is to calculate the length once or look for the null character instead. 一个简单的解决方案是一次计算长度,或者查找空字符

// for(i = 0; i < strlen(str); i++) {
S = strlen(str);
for(i = 0; i < S; i++) {
// or
for(i = 0; str[i]; i++) {

The same thing happens with the inner loop too. 内循环也发生同样的事情。 Yet a smart compiler can see that sChar does not change and may take advantage of understanding strlen() has no side effects that would cause for a different result. 但是,精明的编译器可以看到sChar不会更改,并且可以利用了解strlen()优势而不会导致不同的结果。 With such an optimization strlen(sChar) may be truly called once, even if strlen(sChar) in inside the higher for (i...) loop. 有了这样一个优化strlen(sChar)可真正称为一次,即使strlen(sChar)在内部较高for (i...)循环。

Still it is easy and idiomatic to just test for the null character . 仅仅测试空字符仍然是容易和惯用的。

    // for(j = 0; j < strlen(sChar); j++)
    // better as
    for(j = 0; sChar[j]; j++)

Yet why does this not apply to the for(i = 0; i < strlen(str); i++) loop? 但是,为什么这不适用于for(i = 0; i < strlen(str); i++)循环?

Within that loop, code can modify str[] and so the compiler cannot make the optimization as with for(j = 0; sChar[j]; j++) . 在该循环中,代码可以修改str[] ,因此编译器无法像for(j = 0; sChar[j]; j++)那样进行优化。

This also begs the question, what should code do if the replacement character rChar is the null character ? 这也引出了一个问题,如果替换字符rChar空字符 ,代码应该怎么做?

As I see it, code could either continue, replacing with a '\\0 multiple times or simple return after this first. 如我所见,代码可以继续执行,可以多次替换为'\\0 ,也可以在第一次执行后简单返回。

       str[i] = rChar;
       if (rChar == '\0') return; // Possible way to handle \0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM