从stdin读取输入直到空行

时间:2014-12-22 17:43:29

标签: c parsing input stdin scanf

我想解析输入,例如:

1 2 3\n4 5 6\n7 8 9\n\n

并且对于每一行保存int中的每个值,将它打印到stdout直到我得到一个空行,所以对于这个例子,我会得到:

1 2 3
1 2 3
4 5 6
4 5 6
7 8 9
7 8 9

我尝试过像

这样的事情
int n1, n2, n3;
while(scanf ("%d %d %d\n", n1, n2, n3) != EOF) {
    printf("%d %d %d\n", n1, n2, n3);
    fflush(stdout);
}

但它似乎不起作用。有没有简单的方法呢?

2 个答案:

答案 0 :(得分:2)

scanf无法实现您要执行的操作,因为它会一直读到条件,并且%d说明符将忽略'\n'换行符,我建议使用此代码

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

int  main()
{
    int n1, n2, n3;
    char line[64];

    /* read at least 63 characters or unitl newline charater is encountered with */
    /*    fgets(line, sizeof line, stdin) */
    /* if the first character is a newline, then it's an empty line of input */
    while ((fgets(line, sizeof line, stdin) != NULL) && (line[0] != '\n'))
    {
        /* parse the read line with sscanf */
        if (sscanf(line, "%d%d%d", &n1, &n2, &n3) == 3)
        {
            printf("%d %d %d\n", n1, n2, n3);
            fflush(stdout);
        }
    }
    return 0;
}

虽然这段代码有效,但它不健壮,因为在WhozCraig下面评论的情况下会失败,所以这是一种方法,可以让你免受问题的困扰

#include <stdio.h>
#include <string.h>
#include <ctype.h> /* for isspace */

int isEmpty(const char *line)
{
    /* check if the string consists only of spaces. */
    while (*line != '\0')
    {
        if (isspace(*line) == 0)
            return 0;
        line++;
    }
    return 1;
}

int  main()
{
    int n1, n2, n3;
    char line[64];

    while ((fgets(line, sizeof line, stdin) != NULL) && (isEmpty(line) == 0))
    {
        if (sscanf(line, "%d%d%d", &n1, &n2, &n3) == 3)
        {
            printf("%d %d %d\n", n1, n2, n3);
            fflush(stdout);
        }
    }
    return 0;
}

答案 1 :(得分:0)

我真的不喜欢所提供的任何答案,因为它们也没有捕获输入。我需要捕获整个读取内容并批量处理它们。所以这就是我想出来的:

char * readFromFileUntilBlankLine(FILE *in) {
    int growBy = 1000;
    int allocatedSize = growBy;
    char *buffer = malloc(allocatedSize * sizeof(char));
    strcpy(buffer, "");

    char * line = NULL;
    size_t len = 0;
    ssize_t read = 0;

    while ((read = getline(&line, &len, in)) != EOF) {
        // Are we done? Is this blank?
        if (line[0] == '\n') {
            free(line);
            return buffer;
        }

        // Ensure there is enough space in buffer for line
        int newSize = strlen(buffer) + read + 1;
        if (newSize > allocatedSize) {
            allocatedSize = newSize + growBy;
            buffer = realloc(buffer, allocatedSize * sizeof(char));
        }
        strcat(buffer, line);

        free(line);
        line = NULL;
    }

    if (line) {
        free(line);
    }

    return buffer;
}

这会遇到前一个回复中讨论的"\n \n"问题,但足以满足我的需求。