输入最后一个数组元素时出现分段错误

Spa*_*row 1 c arrays string

我想输入一组蜇伤.要输入的字符串数等于测试用例数.但是当我尝试输入最后一个元素时,我得到了一个分段错误.这是代码.

int main()
{
    int test_cases=0;
    scanf("%d",&test_cases);
    char t[100][test_cases];
    int length=0;
    int i;

    for(i=0;i<test_cases;++i)
    {
        fgets(t[i],100,stdin);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

mac*_*fij 5

考虑一下你的代码:

scanf("%d",&test_cases);
char t[100][test_cases];
Run Code Online (Sandbox Code Playgroud)

这声明了一个char数组,可以容纳100个条目,每个条目都很test_cases长.然后在你的循环中:

for(i=0;i<test_cases;++i)
{
    fgets(t[i],100,stdin);
}
Run Code Online (Sandbox Code Playgroud)

看看如何fgets宣布:

char *fgets(char *s, int size, FILE *stream);
Run Code Online (Sandbox Code Playgroud)

您正在为每个条目写入一个长度为100个字节的输入.早些时候你已经宣布它很test_cases长.假设您test_cases的等于3,并且您已添加代码以打印出已存储的字符:

for(i=0;i<test_cases;++i)
{
    printf("%s\n", t[i]);
}
Run Code Online (Sandbox Code Playgroud)

然后键入以下顺序:

abc
def
Run Code Online (Sandbox Code Playgroud)

哎呀,你想输入第三个字符串,但循环终止.你的输出是

abcdef
def
Run Code Online (Sandbox Code Playgroud)

发生了什么?首先,如果你已经按下回车键,而scanf荷兰国际集团test_cases的变量,有标准输入悬空换行符,它是由与fgets读取.然后,fgets读入abct [1],但终止字符串的空字符存储在下一行.那是因为多维数组连续存储在内存中.后来,def被阅读并\0丢失.你想用printf功能打印你的行.printf继续打印字符,直到遇到\0字符.def的终止字符存储在下一行,因此printf终止于它.第二个输入正确打印.
目前,t数组看起来像:

t[0]   -   \n
t[1]   -   abc
t[2]   -   def
t[3]   -   \0

/* in memory: */
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| \n  |     |     |  a  |  b  |  c  |  d  |  e  |  f  | \0  |     |     | 
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ . . .
|_________________|_________________|_________________|_________________|
       t[0]              t[1]              t[2]              t[3] 
Run Code Online (Sandbox Code Playgroud)

幸运的是,你有更多的行来存储\ 0.
所以你有一个错字.你可能想要声明一个char数组,它可以保存test_cases每个100字节长的条目,即

char t[test_cases][100]
Run Code Online (Sandbox Code Playgroud)

但是,你仍然会丢失一行数组,因为它fgets会停止读取悬挂的换行符(有100个字节未使用!).要解决这个问题,在scanf之后你可以调用一个getchar()函数,或按ctrl + d组合键(这会导致发送EOF).Scanf需要知道你完成了specyfing test_cases.并且还记得为\ 0终止字符留出额外的空间.