鉴于您想识别2 7 A BUL
,您不能安全地使用:
int e,m;
char id[1], modelo[3];
sscanf(frase[i], "%d %d %s %s", &e, &m, &id, &modelo);
首先,您不应该在预期char (*)[]
a 的地方传递值;char *
不要取数组的地址;通过id
并且modelo
只有。如果您打开警告,GCC 会警告您。如果你正在学习 C,你不能不打开警告(-Wall
至少使用;-Wall -Wextra
如果可能的话)。
接下来,第一个%s
将读取任意数量的字符并将结果以空值结尾。这将覆盖id
数组的末尾。而且你不能安全地读入 3 个字符modelo
。因此,您有两个堆栈溢出问题。
你应该写:
int e, m;
char id[2], modelo[4];
if (sscanf(frase[i], "%d %d %1s %3s", &e, &m, id, modelo) != 4)
...oops...
也许:
int e, m;
char id;
char modelo[4];
if (sscanf(frase[i], "%d %d %c %3s", &e, &m, &id, modelo) != 4)
...oops...
或者,您可以使用char id[1];
and %c
,但这很危险;结果不是以 null 结尾的字符串。
您的主要输入循环也值得怀疑。您可以feof()
在 之后立即使用,但测试本身fgets()
的结果更为传统;fgets()
它告诉你它是否成功。该代码可能应该是:
char frase[20][12];
for (int linha = 0; i < sizeof(frase) / sizeof(frase[0]); i++)
{
if (fgets(frase[linha] ,sizeof(frase[linha]), stdin) == 0)
break;
}
这样可以避免重复 20 或 12,但可以保护您免受过多行的影响。它不能保护您免受超长线路的伤害;你可以添加:
size_t len = strlen(frase[linha]);
assert(len != 0);
if (frase[len-1] != '\n')
...input was too long...
到循环。
您还可以考虑在主输入循环中执行sscanf()
和调用;enfila()
那么你就不需要frase
数组是多维的了。
将所有更改放在一起:
char frase[4096];
while (fgets(frase, sizeof(frase), stdin) != 0)
{
int e;
int m;
char id[2];
char modelo[4];
if (sscanf(frase, "%d %d %1s %3s", &e, &m, id, modelo) == 4)
enfila(e, m, id, modelo, l); // l is the parameter to the function
else
...report error...
}
使用fgets()
andsscanf()
绝对是正确的方法。这意味着错误报告可以显示整个输入行,而不是任何被破坏的仍然scanf()
留在后面的不可读的内容。