我想输入一组蜇伤。要输入的字符串数等于测试用例数。但是当我尝试输入最后一个元素时,我得到了一个分段错误。这是代码。
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;
}
答案 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]);
}