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

时间:2014-08-15 06:28:54

标签: 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;
}

3 个答案:

答案 0 :(得分:5)

考虑一下你的代码:

scanf("%d",&test_cases);
char t[100][test_cases];

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

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

了解fgets的声明方式:

char *fgets(char *s, int size, FILE *stream);

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

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

然后输入以下顺序:

abc
def

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

abcdef
def

发生什么事了?首先,如果你在scanf test_cases变量时点击输入,则stdin上有一个悬空的换行符,它由fgets读取。然后,fgets读入abc到t [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] 

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

char t[test_cases][100]

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

答案 1 :(得分:2)

数组维度错误。使用

char t[test_cases][100];

而不是

char t[100][test_cases];

答案 2 :(得分:-2)

您可以使用以下代码读取整个字符串。

int test_cases;
char tmp[1];
scanf("%d", &test_cases);
gets(tmp);
char *t[100];
int length = 0;
int i;
for (i = 0; i<test_cases; i++)
{
    t[i] = (char*)malloc(test_cases);
    gets(t[i]);
}