将scanf BEFOR for循环与fgets一起使用会将[0]返回为空

将scanf BEFOR for循环与fgets一起使用会将[0]返回为空,c,C,所以我真的不明白为什么scanf会弄乱[0]。当我打印出数组时,[0]是空的,在我需要[0]的地方,它存储在[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++) {

所以我真的不明白为什么scanf会弄乱[0]。当我打印出数组时,[0]是空的,在我需要[0]的地方,它存储在[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;
}
#包括
#包括
int main(int argc,char*argv[])
{
char*a[128];
int i;
int-num;
scanf(“%d”和&num);
对于(i=0;i<2;i++){
a[i]=malloc(50*sizeof(char));
fgets(a[i],100,标准偏差);
}
printf(“[0]=%s[1]=%s”,a[0],a[1]);
返回0;
}
您的
scanf()
并没有破坏
a[0]
,至少不是以您似乎认为的方式,通过某种方式破坏其存储区域。这在很大程度上是一个混合不同输入“方法”的问题

您的
scanf/fgets
组合的实际情况是,
scanf
正在获取整数,但没有读取您在该数字末尾输入的换行符,因此第一个
fgets
将获取该整数

ISO标准规定如下(按规定顺序):

除非规范包含[、c或n说明符,否则将跳过输入空格字符(由isspace函数指定)

输入项从流中读取,除非规范包含n说明符。输入项定义为不超过任何指定字段宽度的最长输入字符序列,是匹配输入序列的前缀或前缀

输入项后的第一个字符(如果有)保持未读状态

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


但是,我会告诉你什么可能会把它弄糟(取决于输入行的长度),事实上,你为每个
a[I]
分配50个字符的空间,然后最多读取100个字符。这是未定义的行为


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

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

scanf("%d", &num);
进入:

这样它就能抓住并扔掉剩下的线

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

还有一件事,请不要通过将事物乘以
sizeof(char)
-根据标准,该值始终为1。

您的
scanf()
不会弄乱您的
a[0]
,至少不像你想象的那样,通过某种方式破坏了它的存储区域。这在很大程度上是一个混合不同输入“方法”的问题

您的
scanf/fgets
组合的实际情况是,
scanf
正在获取整数,但没有读取您在该数字末尾输入的换行符,因此第一个
fgets
将获取该整数

ISO标准规定如下(按规定顺序):

除非规范包含[、c或n说明符,否则将跳过输入空格字符(由isspace函数指定)

输入项从流中读取,除非规范包含n说明符。输入项定义为不超过任何指定字段宽度的最长输入字符序列,是匹配输入序列的前缀或前缀

输入项后的第一个字符(如果有)保持未读状态

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


但是,我会告诉你什么可能会把它弄糟(取决于输入行的长度),事实上,你为每个
a[I]
分配50个字符的空间,然后最多读取100个字符。这是未定义的行为


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

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

scanf("%d", &num);
进入:

这样它就能抓住并扔掉剩下的线

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


还有一件事,请不要通过将事物乘以
sizeof(char)
-根据标准,该值始终为1。

假设我输入:1[enter]这是字符串[enter]假设我输入:1[enter]这是字符串[enter]