如何在C中迭代字符串?
现在我正在尝试这个:
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s %s sourcecode input", argv[0], argv[1]);
}
else {
char source[] = "This is an example.";
int i;
for (i = 0; i < sizeof(source); i++) {
printf("%c", source[i]);
}
}
getchar();
return 0;
}
这也不起作用:
char *source = "This is an example.";
int i;
for (i = 0; i < strlen(source); i++){
printf("%c", source[i]);
}
我收到错误
Test.exe 中 0x5bf714cf (msvcr100d.dll) 处出现未处理的异常:0xC0000005:在位置 0x00000054 读取时发生访问冲突。
(从德语大致翻译)
那么我的代码有什么问题吗?
Right now I'm trying this:
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s %s sourcecode input", argv[0], argv[1]);
}
else {
char source[] = "This is an example.";
int i;
for (i = 0; i < sizeof(source); i++) {
printf("%c", source[i]);
}
}
getchar();
return 0;
}
This does also NOT work:
char *source = "This is an example.";
int i;
for (i = 0; i < strlen(source); i++){
printf("%c", source[i]);
}
I get the error
Unhandled exception at 0x5bf714cf (msvcr100d.dll) in Test.exe: 0xC0000005: Access violation while reading at position 0x00000054.
(loosely translated from german)
So what's wrong with my code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
您可以只检查 NULL 字符,而不是像上面建议的那样使用 strlen:
Rather than use strlen as suggested above, you can just check for the NULL character:
sizeof(source)
返回指针char*
所需的字节数。您应该将其替换为strlen(source)
,这将是您尝试显示的字符串的长度。另外,您可能应该将
printf("%s",source[i])
替换为printf("%c",source[i])
因为您正在显示一个角色。sizeof(source)
returns the number of bytes required by the pointerchar*
. You should replace it withstrlen(source)
which will be the length of the string you're trying to display.Also, you should probably replace
printf("%s",source[i])
withprintf("%c",source[i])
since you're displaying a character.这应该有效
This should work
C 字符串的最后一个索引始终是整数值 0,因此称为“空终止字符串”。由于整数 0 与 C 中的布尔值 false 相同,因此您可以使用它为 for 循环创建一个简单的 while 子句。当它到达最后一个索引时,它会找到一个零并将其等于 false,从而结束 for 循环。
The last index of a C-String is always the integer value 0, hence the phrase "null terminated string". Since integer 0 is the same as the Boolean value false in C, you can use that to make a simple while clause for your for loop. When it hits the last index, it will find a zero and equate that to false, ending the for loop.
sizeof(source)
返回给您的是char*
的大小,而不是字符串的长度。您应该使用strlen(source)
,并且应该将其移出循环,否则您将在每个循环中重新计算字符串的大小。%s
格式修饰符进行打印,printf
正在寻找char*
,但实际上您传递的是char< /代码>。您应该使用
%c
修饰符。sizeof(source)
is returning to you the size of achar*
, not the length of the string. You should be usingstrlen(source)
, and you should move that out of the loop, or else you'll be recalculating the size of the string every loop.%s
format modifier,printf
is looking for achar*
, but you're actually passing achar
. You should use the%c
modifier.只需用 strlen 更改 sizeof 即可。
像这样:
Just change sizeof with strlen.
Like this:
这是 11 年前的文章,但与正在学习 C 的人相关。我不明白为什么我们对如此基本的事情有这么多讨论和分歧。 C、IE 中的字符串文字“引号之间的文本”在最后一个字符后有一个隐式的空终止符。不要让这个名字让您感到困惑。空终止符等于数字 0。其用途正是 OP 所需要的:
C 中的 char 是一个 8 位整数,具有相应字符的数字 ASCII 值。这意味着在 char[19] 之前,source[i] 是一个正整数,char[19] 是最后一个“.”之后的空终止符。空字符是 ASCII 0。这是循环终止的地方。该循环迭代每个字符,而不考虑数组的长度。
This is 11 years old but relevant to someone who is learning C. I don't understand why we have all this discussion and disagreement about something so fundamental. A string literal in C, I.E. "Text between quotes" has an implicit null terminator after the last character. Don't let the name confuse you. The null terminator is equal to numeric 0. Its purpose is exactly what OP needs it for:
A char in C is an 8-bit integer with the numeric ASCII value of the corresponding character. That means source[i] is a positive integer until char[19], which is the null terminator after the final '.' The null character is ASCII 0. This is where the loop terminates. The loop iterates through every character with no regard for the length of the array.
将 sizeof 替换为 strlen 就可以了。
Replace sizeof with strlen and it should work.
sizeof(source)
返回指针的 sizeof,因为 source 被声明为 char *。正确的使用方法是
strlen(source)
。下一步:
需要字符串。即 %s 需要字符串,但您正在循环中迭代以打印每个字符。因此使用%c。
但是,您使用索引 i 访问(迭代)字符串的方式是正确的,因此其中没有其他问题。
sizeof(source)
returns sizeof a pointer as source is declared as char *.Correct way to use it is
strlen(source)
.Next:
expects string. i.e %s expects string but you are iterating in a loop to print each character. Hence use %c.
However your way of accessing(iterating) a string using the index i is correct and hence there are no other issues in it.
您需要一个指向第一个字符的指针才能拥有 ANSI 字符串。
会完成这项工作
另外,当然你应该指的是
strlen(source)
,而不是sizeof(source)
。You need a pointer to the first char to have an ANSI string.
will do the job
Plus, of course you should have meant
strlen(source)
, notsizeof(source)
.您想要:
sizeof
为您提供指针的大小,而不是字符串。但是,如果您将指针声明为数组,它就会起作用:但是如果将数组传递给函数,它也会衰减为指针,这就是为什么对于字符串最好始终使用
strlen
。另请注意其他人关于更改 printf 以使用 %c 的说法,并且考虑到 mmyers 对效率的评论,最好将对
strlen
的调用移出循环:或重写循环:
You want:
sizeof
gives you the size of the pointer, not the string. However, it would have worked if you had declared the pointer as an array:but if you pass the array to function, that too will decay to a pointer which is why for strings it's best to always use
strlen
.Also note what others have said about changing printf to use %c, and, taking mmyers comments on efficiency into account, it would be better to move the call to
strlen
out of the loop:or rewrite the loop:
一种常见的习惯用法是:
一些注意事项:
*c++
递增c
并返回c
的取消引用的旧值。printf("%s")
打印一个以 null 结尾的字符串,而不是一个字符。这就是您的访问违规的原因。One common idiom is:
A few notes:
*c++
incrementsc
and returns the dereferenced old value ofc
.printf("%s")
prints a null-terminated string, not a char. This is the cause of your access violation.优化方法:
大多数 C 字符串都是以 null 终止的,这意味着一旦字符变成
'\0'
循环就应该停止。*++string
将指针移动一个字节,然后取消引用它,然后重复循环。这比
strlen()
更高效的原因是 strlen 已经循环遍历字符串来查找长度,因此您实际上可以使用strlen 循环两次(比需要的多一次) ()
。An optimized approach:
Most C strings are null-terminated, meaning that as soon as the character becomes a
'\0'
the loop should stop. The*++string
is moving the pointer one byte, then dereferencing it, and the loop repeats.The reason why this is more efficient than
strlen()
is because strlen already loops through the string to find the length, so you would effectively be looping twice (one more time than needed) withstrlen()
.