使用 memset 时,阵列未正确重置
Posted
技术标签:
【中文标题】使用 memset 时,阵列未正确重置【英文标题】:Array is not reseting correctly, when using memset 【发布时间】:2019-04-21 14:35:22 【问题描述】:当我从stdin
获取一个对于c
来说太大的值时,重置的行为不符合预期。系统会再次提示用户输入代码,但在输入后需要输入的位置会出现一个额外的新行,而不是长度检查失败。
void clear(void)
while (getchar() != '\n')
;
int add_flight(code_t codes[], int lf)
char c[MAX_CODE_LEN + 1];
int s = 0;
while (s == 0)
printf("Enter code>\n");
if (fgets(c, sizeof c, stdin))
printf("%s", c);
if ('\n' == c[0])
printf("Invalid input\n");
else if (c[sizeof c - 1] == '\0' && c[sizeof c - 2] != '\n')
clear();
printf("Invalid input\n");
memset(c, 0, sizeof c);
else
strcpy(codes[lf].id, c);
s = 1;
break;
return 0;
任何帮助将不胜感激。
【问题讨论】:
发布code_t
的定义。特别是.id
成员的内存是怎么确定的?
【参考方案1】:
你的代码有几个问题:
clear
函数不测试文件结尾,如果标准输入在没有尾随换行符的情况下关闭,则会导致无限循环,就像从空文件重定向输入时的情况一样。
过长输入行的测试不正确:如果输入未填充数组,则数组的最后一个字符未定义。您应该在去除尾随换行符后测试 strlen(c) == sizeof(c) - 1
。
c
是 char
数组的一个非常令人困惑的名称。此名称通常用于int
以接收字节值。将数组命名为 buf
以提高可读性。
memset
没有用,因为您要在数组中读入新行。
缺少code_t
的定义。如果其id
成员数组的大小至少不是MAX_CODE_LEN + 1
,则行为将是未定义的。
此外,您将尾随换行符复制到codes[lf].id
,这可能不正确。
如果id
定义为包含MAX_CODE_LEN
字符,即char id[MAX_CODE_LEN + 1];
用于额外的空终止符,buf
应该有一个额外的字节用于用户键入的换行符,因此char buf[MAX_CODE_LEN + 2];
这是修改后的版本:
int clear(void)
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
int add_flight(code_t codes[], int lf)
char buf[MAX_CODE_LEN + 2];
for (;;)
printf("Enter code>\n");
if (fgets(buf, sizeof buf, stdin))
printf("%s", buf);
/* remove the trailing newline if present */
size_t len = strlen(buf);
if (len > 0 && buf[len - 1] == '\n')
buf[--len] = '\0';
if (len == sizeof(buf) - 1)
/* line too long: consume the rest of the input line */
printf("Invalid input\n");
if (clear() == EOF)
break;
else if (len == 0)
/* empty line */
printf("Invalid input\n");
else
strcpy(codes[lf].id, buf);
return 1; // return success
else
break;
return 0; // premature end of file: return failure
【讨论】:
感谢@chqrlie,效果很好。id
的定义与 buf
相同,所以我怀疑会有问题
实际上,在这种情况下,buf
应该定义为char buf[MAX_CODE_LEN + 2];
以允许用户输入MAX_CODE_LEN
字符和一个带有额外元素的换行符空终止符。以上是关于使用 memset 时,阵列未正确重置的主要内容,如果未能解决你的问题,请参考以下文章