c - 使用 memset 时,数组未正确重置

标签 c arrays memset fflush

当我从 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;
}

如有任何帮助,我们将不胜感激。

最佳答案

你的代码有几个问题:

  • 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
}

关于c - 使用 memset 时,数组未正确重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55783655/

相关文章:

java - Java 中的 C 指针等价

Javascript删除比拼接

c# - Array.GetValue() 返回结构对象的新实例

c - aio_write 和 memset 参数无效和段错误(核心已转储)

optimization - 为什么 memset 很慢?

c++ - memset() 在构造函数中初始化对象?

c - 当命令访问不存在的文件时来自 popen 的错误状态

c - Linux的消息队列有什么缺点?

c - Linux 内核系统调用返回未给定的指针

java - Hangman Java 游戏打印错误和正确的猜测