检查C中的标准DIN管道是否为空

检查C中的标准DIN管道是否为空,c,stdin,C,Stdin,我使用用户输入填充二维数组。用户在一行中输入数字,然后我使用嵌套循环填充数组,如下所示: //User inputs: "1 2 3 4 5" for(i = 0; i < r; i++){ for(j = 0; j < c; j++){ scanf("%d", &arr[i][j]); } } //用户输入:“1 2 3 4 5” 对于(i=0;i

我使用用户输入填充二维数组。用户在一行中输入数字,然后我使用嵌套循环填充数组,如下所示:

//User inputs: "1 2 3 4 5"

for(i = 0; i < r; i++){
    for(j = 0; j < c; j++){
            scanf("%d", &arr[i][j]);
    }
 }
//用户输入:“1 2 3 4 5”
对于(i=0;i
但是,问题是,如果用户在有6个整数的空间时输入5个整数,它只会等待另一个输入。我如何检测是否有不足的数字

我尝试过使用此功能,但不起作用:

for(i = 0; i < r; i++){
    for(j = 0; j < c; j++){
        if (!feof(stdin)){
            scanf("%d", &arr[i][j]);
        }
        else{
            printf("insufficient datapoints\n");
        }
    }
 }
(i=0;i{ 对于(j=0;j您可以在流中使用peek-ahead并在实际使用字符之前测试字符。(在c中有点像)

您可以使用它来忽略空白(您需要这样做)

您还可以使用此窥视值指示是否输入了不足的字符

需要在实际读取(scanf)之前进行窥视

下面添加了粗略的示例代码

#include <stdio.h>
#include <ctype.h>

int r=3; 
int c=2;

int arr[100][100]; // FIX magic

int main(int argc, char** argv[]) {

  for(int i=0; i<r; i++) {
    for(int j=0; j<c; j++) {

      if (feof(stdin)) {
        // error check and error / normal exit etc.
        printf("eof\n");
      }

      char c=getchar();

      if (c=='\n') {
        // error check and error / normal exit here
        printf("newline\n");

      } else if (isspace(c)) {
        // advance and remove them - watch for end of stream when winding
        printf("advance and discard whiitespace\n");

      } else { // add check for isdigit
        // push back
        ungetc(c, stdin);
        printf("ungetc\n");
      }

      scanf("%d", &arr[i][j]);  
      printf("got %d\n", arr[i][j]);   
    }    
  }

  return 0;
}
#包括
#包括
int r=3;
int c=2;
int arr[100][100];//修理魔法
int main(int argc,字符**argv[]{

对于(int i=0;i实现目标的一种方法是使用
fgets()
而不是
scanf()
一次读取一行输入。然后可以使用
strtok()
将输入行分解为令牌,
strtol()
将令牌解析为数字。与
scanf()相比
,使用
fgets
处理非结构化用户输入要容易得多

下面的代码就是这样做的。如果输入行中的元素太多、太少,或者其中一个元素不是有效的数字,则会打印一条消息,并且必须再次输入该行

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF_SIZE  1000

int main(void)
{
    size_t r = 3;
    size_t c = 5;
    size_t i, j;
    char buffer[BUF_SIZE];
    char *token;
    char *tail;
    const char delims[] = " \t\r\n";
    int arr[r][c];
    int temp_val;

    printf("Enter rows of %zu data elements:\n", c);

    for(i = 0; i < r; i++){
        j = 0;

        if (fgets(buffer, BUF_SIZE, stdin) == NULL) {
            perror("Error in fgets()");
            exit(EXIT_FAILURE);
        }

        token = strtok(buffer, delims);
        while (token != NULL) {
            temp_val = strtol(token, &tail, 10);
            if (*tail == '\0') {
                arr[i][j] = temp_val;
                ++j;
            } else {                // token not a valid number
                j = 0;
                break;
            }

            if (j > c) {            // too many input values
                break;
            }

            token = strtok(NULL, delims);
        }

        if (j != c) {
            printf("insufficient datapoints\n");
            --i;                    // enter row again
        }
    }

    for (i = 0; i < r; i++) {
        for (j = 0; j < c; j++) {
            printf("%5d", arr[i][j]);
        }
        putchar('\n');
    }

    return 0;
}
当用户输入每一行时,
strtok()
用于将行拆分为标记。标记分隔符列表存储在
delims[]
。请注意,标记可以用空格或制表符分隔;分隔符本身不是标记的一部分,因此包含
\r
\n
可确保这些字符不会成为行中最终标记的一部分

当找到令牌时,如果可能,将使用
strtol()
将其转换为整数
,指针
tail
指向标记中不属于数字的第一个字符;如果
tail
指向
NUL
终止符,则整个字符串被解析为数字,否则输入被视为错误,必须重新输入行

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF_SIZE  1000

int main(void)
{
    size_t r = 3;
    size_t c = 5;
    size_t i, j;
    char buffer[BUF_SIZE];
    char *token;
    char *tail;
    const char delims[] = " \t\r\n";
    int arr[r][c];
    int temp_val;

    printf("Enter rows of %zu data elements:\n", c);

    for(i = 0; i < r; i++){
        j = 0;

        if (fgets(buffer, BUF_SIZE, stdin) == NULL) {
            perror("Error in fgets()");
            exit(EXIT_FAILURE);
        }

        token = strtok(buffer, delims);
        while (token != NULL) {
            temp_val = strtol(token, &tail, 10);
            if (*tail == '\0') {
                arr[i][j] = temp_val;
                ++j;
            } else {                // token not a valid number
                j = 0;
                break;
            }

            if (j > c) {            // too many input values
                break;
            }

            token = strtok(NULL, delims);
        }

        if (j != c) {
            printf("insufficient datapoints\n");
            --i;                    // enter row again
        }
    }

    for (i = 0; i < r; i++) {
        for (j = 0; j < c; j++) {
            printf("%5d", arr[i][j]);
        }
        putchar('\n');
    }

    return 0;
}

如果
scanf()
不要返回
EOF
管道未关闭。@ccpgh我该怎么做?使用
fgets
strtok
?这个测试应用程序只是坐在那里,如果管道是空的,它什么也不做,这违背了检查管道是否是空的目的…所以,不确定这应该实现什么。