[英]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
: 首先,当您遍历
str
和sChar
:
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.