简体   繁体   English

C getline() 读取最后一行两次

[英]C getline() read last line twice

just wondering why my function getline() read the last line twice.只是想知道为什么我的函数 getline() 读取最后一行两次。

I'm supposed to read from a tsv file and print each line to stdout.我应该从 tsv 文件中读取并将每一行打印到标准输出。 But somehow keep reading the last row twice.但不知何故继续阅读最后一行两次。

            char *line = NULL;
            size_t line_buf_size = 0;
            ssize_t line_size;
            line_size = getline(&line, &line_buf_size, stdin);
            int row = 0;
    
            while (line_size >= 0)
            {
                row++;
                line_size = getline(&line, &line_buf_size, stdin);
                printf("%s", line);

if a file looks like this如果文件看起来像这样

A B C
D E F

it prints它打印

A B C
D E F
D E F

How do i fix it?我如何解决它?

You're actually skipping the first line.你实际上跳过了第一行。

Since you're reading from STDIN, what you type, there is no file.由于您是从 STDIN 读取的,因此您键入的内容没有文件。 Your output and input are mixed up.你的输出和输入混淆了。 We can see this by changing your printf to add a prefix printf("output: %s", line);我们可以通过更改printf添加前缀printf("output: %s", line);来查看这一点printf("output: %s", line); . .

A B C   <-- this is your input echoed to the screen
D E F   <-- and this
output: D E F
output: 

Your code is reading the first line, checking how long it is, and then reading the next line without printing the first.您的代码正在读取第一行,检查它的长度,然后读取下一行而不打印第一行。 That's why you're missing the first line.这就是为什么你错过了第一行。

We get the extra blank print at the end because you're checking if you read anything from the previous line.我们在最后得到了额外的空白打印,因为您正在检查是否从前一行中读取了任何内容。 Then you're reading and printing immediately without checking.然后,您无需检查即可立即阅读和打印。

// Read the first line.
line_size = getline(&line, &line_buf_size, stdin);
int row = 0;

// Check if you read anything from the *previous* line.
while (line_size >= 0)
{
    row++;

    // Read the next line overwriting the first line.
    line_size = getline(&line, &line_buf_size, stdin);

    // Print the second and subsequent lines without first checking
    // if you read anything.
    printf("%s", line);
}

Instead, read, check, and print.相反,阅读、检查和打印。

#include <stdio.h>

int main() {
    char *line = NULL;
    size_t line_buf_size = 0;
    int row = 0;

    // Read and check.
    while (getline(&line, &line_buf_size, stdin) > -1)
    {
        row++;
        // Print.
        printf("output: %s", line);
    }
}

And we get interleaved inputs and outputs.我们得到交错的输入和输出。

A B C
output: A B C
D E F
output: D E F

You don't need to store the line length, but if you did put parens around the assignment before you compare it.您不需要存储行长度,但如果您在比较之前确实在分配周围放置了括号。 That ensures doing (line_size = getline(...)) > -1 not line_size = (getline(...) > -1) .这确保了(line_size = getline(...)) > -1而不是line_size = (getline(...) > -1) That is storing the return value of getline in line_size and then checking if it's -1.那就是将 getline 的返回值存储在 line_size 中,然后检查它是否为 -1。 Not checking if getline returned -1 and storing the true/false result into line_size.不检查 getline 是否返回 -1 并将真/假结果存储到 line_size。

    while((line_size = getline(&line, &line_buf_size, stdin)) > -1)

Say getline returns -1 signifying EOF.假设getline返回 -1 表示 EOF。 What do you do next?下一步你要怎么做? You print.你打印。 oops!哎呀!

char *line = NULL;
size_t line_buf_size = 0;
int row = 0;

while ( getline(&line, &line_buf_size, stdin) >= 0 ) {
   ++row;
   printf("%s", line);
}

if (ferror(stdin)) {
   perror("getline");
   exit(1);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM