gpt4 book ai didi

c - 在带有 fgets 的 for 循环之前使用 scanf 返回 a[0] 为空

转载 作者:太空宇宙 更新时间:2023-11-04 07:32:08 25 4
gpt4 key购买 nike

所以我无法真正弄清楚为什么 scanf 会弄乱 a[0]。当我打印出数组时,a[0] 是空的,而我想要 a[0] 的地方存储在 a[1] 中。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
char *a[128];
int i;
int num;

scanf("%d", &num);

for (i = 0; i < 2; i++) {
a[i] = malloc(50*sizeof(char));
fgets(a[i], 100, stdin);
}

printf("[0] = %s [1] = %s", a[0], a[1]);

return 0;
}

最佳答案

您的scanf() 没有弄乱您的a[0],至少不是您认为的那样,通过以某种方式破坏了它的存储区域。这是混合不同输入“方法”的一个非常大的问题。

您的scanf/fgets 组合实际发生的是scanf 正在获取整数,但没有读取您在该数字末尾输入的换行符, 所以第一个 fgets 会选择它。

ISO 标准这样规定(按指定顺序):

Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier.

An input item is read from the stream, unless the specification includes an n specifier. An input item is defined as the longest sequence of input characters which does not exceed any specified field width and which is, or is a prefix of, a matching input sequence.

The first character, if any, after the input item remains unread.

第一段和最后一段很重要。第一个表示跳过前导空格,最后一个表示将尾随空格留在输入流中以供稍后读取。


但是,我会告诉你什么可能搞砸了(取决于你输入行的长度),事实上你为每个 a[i] 分配了 50 个字符的空间] 然后将最多 100 个字符读入其中。那是未定义的行为。


如果您想要一个稳健的输入解决方案来正确处理缓冲区大小、检测太长的行、丢弃这些行的剩余部分等等,请参阅 this answer .

或者,如果您想使用非基于行的 scanf 模拟基于行的行为(并且您确定您的行总是小于 100 字节),您可以更改:

scanf("%d", &num);

进入:

char junk[100];
scanf ("%d", &num);
fgets (junk, sizeof (junk), stdin);

以便它捕获并丢弃该行的其余部分。

并且您应该确保 fgets 的最大大小参数与可用内存量匹配(例如在上面的代码中使用 sizeof)。

另一件事,请不要通过将事物乘以 sizeof(char) 来使代码复杂化 - 根据标准,该值始终为 1。

关于c - 在带有 fgets 的 for 循环之前使用 scanf 返回 a[0] 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12792724/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com