在用户输入中处理EOF

时间:2015-05-13 16:38:16

标签: c arrays error-handling

我正在编写一个小程序,允许用户输入矩阵的尺寸mn,然后根据自己的喜好填充该矩阵。要读入数字,我使用fgets()将用户输入作为字符串读取,然后通过strtol()进行转换。我还会通过fgets()删除新行strcspn()附加内容,并在用户输入a12a或仅换行\n时进行错误处理。但是通过EOF输入Ctrl + D令我头疼。我读了几个关于这个的stackoverflow线程,我知道在某些情况下需要输入EOF两次。但是,当我发送EOF给我fgets()维度中m的第一个电话时,我将转发到fgets()的下一个电话,其中n读取EOF尺寸,从那里它将跳转到实际的数组输入,它似乎卡住或我进入无限循环。我目前不知道原因,我不知道在这种情况下如何处理#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> int main(int argc, char *argv[]) { /* We use "m_row" and "n_col" to keep track of the matrix dimensions and "m" * and "n" to keep track of the size of dynamically allocated memory. */ unsigned long int m_row; unsigned long int n_col; unsigned long int element; /* Initializing at dummy value to silence compiler. */ m_row = 1; n_col = 1; /* The largest integer that can fit into unsigned long int is a 20-digit * number. */ char save[20]; char *ptr_save; printf("Enter number of rows:\n"); if (fgets(save, sizeof(save), stdin) != NULL) { save[strcspn(save, "\n")] = 0; if (save[0] == '\0') { fprintf(stderr, "Wrong input\n"); exit(EXIT_FAILURE); } m_row = strtol(save, &ptr_save, 10); if (*ptr_save != '\0') { fprintf(stderr, "Wrong input\n"); exit(EXIT_FAILURE); } } printf("Enter number of columns:\n"); if (fgets(save, sizeof(save), stdin) != NULL) { save[strcspn(save, "\n")] = 0; if (save[0] == '\0') { fprintf(stderr, "Wrong input\n"); exit(EXIT_FAILURE); } n_col = strtol(save, &ptr_save, 10); if (*ptr_save != '\0') { fprintf(stderr, "Wrong input\n"); exit(EXIT_FAILURE); } } errno = 0; unsigned long int **arr = calloc(m_row, sizeof(unsigned long int *)); if (arr == NULL) { fprintf(stderr, "%s", strerror(errno)); exit(EXIT_FAILURE); } int i; errno = 0; for(i = 0; i < m_row; i++) { arr[i] = calloc(m_row, sizeof(unsigned long int)); if (arr[i] == NULL) { fprintf(stderr, "%s", strerror(errno)); exit(EXIT_FAILURE); } } int j; for(i = 0; i < m_row; i++) { for(j = 0; j < n_col; j++) { if (fgets(save, sizeof(save), stdin) != NULL) { save[strcspn(save, "\n")] = 0; if (save[0] == '\0') { fprintf(stderr, "Wrong input\n"); exit(EXIT_FAILURE); } element = strtol(save, &ptr_save, 10); if (*ptr_save != '\0') { fprintf(stderr, "Wrong input\n"); exit(EXIT_FAILURE); } arr[i][j] = element; } printf("\n"); } } for (i = 0; i < m_row; i++) { for(j = 0; j < n_col; j++) { printf("%lu\t", arr[i][j]); } printf("\n"); } free(arr); return 0; } 。如果有人能提供一些提示,我会很高兴。这是代码:

concat()

1 个答案:

答案 0 :(得分:2)

错误的分配大小:m_row vs n_col。这可能不是EOF问题。

for (i = 0; i < m_row; i++) {
  // arr[i] = calloc(m_row, sizeof(unsigned long int));
  arr[i] = calloc(n_col, sizeof(unsigned long int));
}

建议初始化m_row = 0; n_col = 0;

代码尝试打印arr,即使由于arr未完全填充EOF。应该避免这种情况。

如果这些问题无法解决问题,请建议在阅读元素之前打印m_rown_col,以验证矩阵大小是否符合预期。

轻微:使用相同大小的整数

 // Rather than 
 unsigned long int m_row;
 ...
 int i;
 for(i = 0; i < m_row; i++) {

 // Use same type: recommend `size_t`
 size_t m_row;
 ...
 size_t i;
 for(i = 0; i < m_row; i++) {

轻微:将strtoul()unsigned long一起使用,而不是strtol()

Minor:“可以放入unsigned long int的最大整数是一个20位数的数字”...... char save[20];误导。 1)pow(2,64)需要20 char,但输入需要考虑'\n''\0',因此应使用char save[20+2]; 2)unsigned long int < em>可能大于64位 - 它必须至少为32位。但这肯定不是这篇文章的主要问题。