C fgets 和 getline 跳过来自标准输入的输入

C fgets and getline skip input from stdin

我在使用 getline/fgets 时遇到问题。我正在尝试从 stdin 中读取数据,同时通过管道传输文件中的输入,然后对其进行处理。虽然它在 opensuse 上与 gcc 4.8.5 一起工作得很好,但它不适用于带有 gcc 7 的 Arch Linux 和带有 gcc 5 的最新 ubuntu。后者将简单地跳过几行输入。 (我正在传输相同的文件)。在这个例子中,我的程序在通过管道输入时会跳过第三行和第四行,但在手动输入时不会。与更大的文件相同,只是总是跳过相同的行。有什么想法吗?非常感激。谢谢。

输入格式(每行后跟一个换行符):

0 1 2
2 3 4
3 4 5
2 4 5
1 2 3
1
2
3

我的代码如下所示:

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

int bytes;
size_t nbytes = 100;
char *str = (char *) malloc(nbytes+1); // 1 byte for [=11=]
long i = 0;
node *itemArray = malloc(sizeof(itemArray));

while ((bytes = getline(&str, &nbytes, stdin) != -1)) {
    char* token;
    char *rest = str;
    int callNums = 0;
    long from = 0;
    long to =  0;
    long weight = 0;

    while((token = strtok_r(rest, " ", &rest))) {
        if(callNums == 0) {
            from = atol(token);
                    }
        if(callNums == 1) to = atol(token);
        if(callNums == 2) weight = atol(token);
        callNums++;
    }

    if(callNums == 3) {
        if(i == 0) {
            itemArray[i].from = from;
            itemArray[i].to = to;
            itemArray[i].weight = weight;
            printf("%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
        }

        if(i > 0) {
            node *tmp = realloc(itemArray, (i * sizeof(itemArray)));
            if(tmp) {
                itemArray = tmp;
                itemArray[i].from = from;
                itemArray[i].to = to;
                itemArray[i].weight = weight;
                printf("%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
            }
            else { printf("realloc failed");
                exit(-1); }
        }
        ++i;
    }
   }
  }
  free(str);
  free(itemArray);
  return(0);
 }

试一试。通过将 itemArray 设置为 NULL,对 realloc 的第一次调用将像 malloc 一样工作。将 str 设置为 NULL 并将 nbytes 设置为 0 应该可以正常使用 getline。
sscanf 应该可以从字符串中扫描三个 long。如果成功扫描了三个,它们将被添加到 itemarray。

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

    int bytes;
    size_t nbytes = 0;
    char *str = NULL;
    long i = 0;
    node *itemArray = NULL;

    while ( ( bytes = getline ( &str, &nbytes, stdin) != -1)) {
        int callNums = 0;
        long from = 0;
        long to =  0;
        long weight = 0;

        if ( 3 == sscanf ( str, "%ld%ld%ld", &from, &to, &weight)) {

            node *tmp = realloc ( itemArray, ( ( i + 1) * sizeof ( *tmp)));
            if(tmp) {
                itemArray = tmp;
                itemArray[i].from = from;
                itemArray[i].to = to;
                itemArray[i].weight = weight;
                printf ( "%li %li %li \n", itemArray[i].from, itemArray[i].to, itemArray[i].weight);
            }
            else { 
                printf("realloc failed");
                exit(-1); 
            }
            ++i;
        }
    }
    free(str);
    free(itemArray);
    return(0);
}