arrays - 将字符串的字母分配到数组中
问题描述
我正在尝试创建一个C
代码,该代码从用户那里获取最大长度为 10 的输入字符串,并将每个字母分配给大小为 10 的数组的不同元素。但是,我无法理解我的结果。我的代码:
char word1[9];
int i;
printf("Enter your first word: \n");
scanf("%s", &word1);
printf("your word is %s \n",word1);
for(i = 0; i < 10; i++)
printf("%d ", word1[i]);
system("pause");
当我输入单词“hello”时,for
循环显示数组的前 6 个元素中的每一个word1
都被分配ASCII
了字母 h、e、l、l、o 的等效数字。理想情况下,最后 4 个元素应该为 0,但它们不是。输出为 [104 101 108 108 111 0 0 0 1 0]。那个1是从哪里来的?同样,如果我输入“hi”,则输出为 [104 105 0 24 -3 127 0 0 1 0]。104 和 105 之后的这些随机数是什么,为什么它们不是 0?
对于上下文,我正在尝试构建一个简单的代码来检查两个输入单词是否是字谜。我的想法是生成 2 个 ASCII 等效数组,然后我可以按升序排序,以便比较每个对应的元素。
附加问题:为什么当我在 for 循环中从 i<10 增加 10 时,输出会显示超过 10 个值?由于数组有 10 个元素,它不应该总是只显示 10 个输出吗?
对不起,如果这是微不足道的,我对C
.
解决方案
你最大的问题是:
- 在调用未定义的行为之前不正确地使用
scanf()
添加。由于数组/指针转换,它已经是一个指针。请参阅:C11 标准 - 6.3.2.1 其他操作数 - 左值、数组和函数指示符 (p3)&
word1
word1
- 您未能使用field-width修饰符来保护您的数组边界,从而允许用户通过输入超出数组可以容纳的字符数来利用您的代码。使用没有字段宽度
scanf()
修饰符的"%s"
转换说明符将输入限制为数组可以容纳的字符数并不比使用. 请参阅:为什么 gets() 如此危险,永远不应该使用!gets()
for
如果您的数组包含少于一个9
字符(应该是11
保存一个10
字符串。)word1
(如果正确读取),则使用循环超出数组的末尾,是一个以空结尾的字符串。您只需循环直到找到字符串结尾(例如,'\0'
其 ASCII 值只是 plain-old 的字符0
)。您不会遍历数组可以保存的最大字符数——它们可能保存未设置的值。
要纠正上述问题以及更多问题,您可以执行以下操作:
#include <stdio.h>
#define MAXCHR 10 /* if you need a constant, #define one (or more) */
int main (void) {
char word1[MAXCHR + 1]; /* to treat chars as a string, you need +1 for \0 */
int i;
fputs ("Enter your first word: ", stdout); /* no conversion, printf not needed */
if (scanf ("%10s", word1) != 1) { /* validate EVERY input, protect */
puts ("EOF encountered on read of word1"); /* array bounds with field-width */
return 0;
}
printf ("your word is: %s\n", word1); /* output word1 */
for (i = 0; word1[i]; i++) /* word1 is a string, loop to end */
printf ("%c ", word1[i]);
putchar ('\n'); /* tidy up with newline */
#if defined (_WIN32) || defined (_WIN64)
system("pause"); /* non-portable, only for windows */
#endif
}
(注意: printf()
仅当您的输出字符串包含转换时才需要输出,否则,puts()
或者fputs()
如果需要行尾控制,则可以)
示例使用/输出
字符数内的基本输入:
$ ./bin/word1
Enter your first word: bananas
your word is: bananas
b a n a n a s
准确输入允许的字符数:
$ ./bin/word1
Enter your first word: 1234567890
your word is: 1234567890
1 2 3 4 5 6 7 8 9 0
输入两倍于数组可以作为字符串保存的字符:
$ ./bin/word1
Enter your first word: 12345678901234567890
your word is: 1234567890
1 2 3 4 5 6 7 8 9 0
(注意:无论您尝试输入多少个字符,只会10
存储以 nul 结尾的字符。请注意,任何未读取的字符都将保持stdin
未读状态 - 只是等着下次输入时咬您。这就是为什么input 应该与fgets()
or POSIX一起使用getline()
,以便消耗整行输入。无论您使用哪个输入功能,您都无法正确使用它,除非您检查返回以确定输入是成功还是失败。)
如果您还有其他问题,请仔细查看并告诉我。
推荐阅读
- javascript - 如何让我的 overflow-x 滚动只使用两个按钮?
- mysql - MariaDB - UPDATE/DELETE 静默失败
- python - 在 Dockerfile 中安装 pandas
- python - python生成固定大小(16字节)的真实随机字符串
- laravel - 如何从 laravel 中的密码重置链接中删除 localhost
- python - 我想通过表单数据发送邮件。我希望接收者被固定,而发送者只改变。我怎样才能做到这一点?
- python - 解压多个值并存储到数据库中失败
- python - VSCode 调试器自动附加到子进程
- tensorflow - TensorBoard 检查时,为什么“tf.nn.bidirectional_dynamic_rnn”在 TPU 上有“不兼容的操作”?
- c# - 如何在 C# 中创建此等效列表?