我正在关注Kernighan和Ritchie的C书,但我在使用字符串方面遇到了一些困难。
在下面的代码中,我看到我的字符串在用getchar()
字符之前通过\0
从用户输入时包含额外的,我会说的是垃圾字符。
以下是代码:
#include <stdio.h>
main() {
char s[200];
int c, i;
printf("Enter input string:\n");
for (i = 0; ( c = getchar()) != '\n'; i++) {
s[i] = c;
}
printf("Contents of input string:\n");
for (i = 0; s[i] != '\0'; i++) {
printf("%d: (%d) = ", i, s[i]);
putchar(s[i]);
printf("\n");
}
return 0;
}
这是输出逐个显示字符数组的每个元素。它意味着以下内容:
Array_element: (ascii_number) = ascii_character
0: (72) = H
1: (101) = e
2: (108) = l
3: (108) = l
4: (111) = o
5: (32) =
6: (87) = W
7: (111) = o
8: (114) = r
9: (108) = l
10: (100) = d
11: (33) = !
12: (-1) = ?
13: (127) =
雅看到元素12和13? (元素14可能是空字符\0
)。威士忌酒。探戈。狐步。
这是真正的踢球者,如果我将角色阵列定义为只有 100个元素而不是200,那么输出是合理的。例如,如果我只是替换
char s[200]
同
char s[100]
然后输出如下:
0: (72) = H
1: (101) = e
2: (108) = l
3: (108) = l
4: (111) = o
5: (32) =
6: (87) = W
7: (111) = o
8: (114) = r
9: (108) = l
10: (100) = d
11: (33) = !
12: (9) =
(我还不确定换行符在哪里。是不是ascii字符#10?)
再次,威士忌探戈狐步舞。
这里发生了什么?
的更新 的
因此,根据下面的答案,当我将我的字符数组设置为100或200个元素时,输出之间的差异实际上是巧合 - 我只是在未初始化的内存中使用垃圾/噪音。
我需要用\0
显式终止我的数组,因为答案清楚地表明了这一点。
答案 0 :(得分:7)
在本练习中,如果您希望在输入后字符串中存在空字符,那么您需要自己添加它。
您正在观察奇数字符,因为C中的变量和数组未初始化:它们可以包含任何垃圾值,可能包括随机放置的空字符。
当您更改数组大小时,您可能会观察到不同的输出,但不要指望任何合理的,预期的或可重复的行为 - 它是未定义的 - 因为这些数组值可以是任何值。
答案 1 :(得分:3)
您需要将空终止符(\0
)放在您收到的字符串的末尾,以便在字符串末尾进行下一次检查停止。
否则,循环将进入垃圾记忆库。
答案 2 :(得分:1)
完成阅读键盘输入后,必须在程序中添加s[i] = '\0';
。否则,你的字符串将是格式错误的。它不包含'\ 0'终止字符。
这是更改后的代码:
#include <stdio.h> main()
{
char s[200];
int c, i;
printf("Enter input string:\n");
for (i = 0; ( c = getchar()) != '\n'; i++)
{
s[i] = c;
}
s[i] = '\0'; //here, I added the '\0' character. (the only change i made in your code.)
printf("Contents of input string:\n");
for (i = 0; s[i] != '\0'; i++) {
printf("%d: (%d) = ", i, s[i]);
putchar(s[i]);
printf("\n");
}
return 0;
}
2 - 字符串s的大小为200,因此您必须关注缓冲区溢出:for (i = 0; ( c = getchar()) != '\n' && i < 199 ; i++)
(最后一个字符为\0
)。您还可以在读取输入字符时调整字符串的大小:
int size = 200;
char* s = malloc(size);
for (i = 0; ( c = getchar()) != '\n'; i++)
{
if(i >= size)
{
char* tmp = malloc(size + 200);
memcpy(tmp , s , size);
size += 200;
free(s);
}
s[i] = c;
}
并且,在代码结束时,添加:
free(s);
//当你不再需要它时,释放最后创建的字符串。