C fgets和getline跳过stdin的输入

时间:2017-07-03 09:45:44

标签: c gcc fgets getline

我在使用getline / fgets时遇到问题。我试图从文件中读取文件,然后处理它。虽然它在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 \0
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);
 }

1 个答案:

答案 0 :(得分:1)

试一试。通过将itemArray设置为NULL,对realloc的第一次调用将像malloc一样。将str设置为NULL并将nbytes设置为0应该可以正常使用getline sscanf应该可以从字符串中扫描三个长整数。如果成功扫描了三个,它们将被添加到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);
}