简体   繁体   中英

how to print line numbers from multiple files without using fgets

在此处输入图像描述 I'm trying to print line numbers in the beginning of the lines without using fgets() yes, it prints line number well when I input multiple files but I want to get result like this. Can you guys help me with this?

Now result

1 I'll always remember
2 the day we kiss my lips
3
4 light as a feather
*5 ####@localhost ~ $*

expect result

1 I'll always remember
2 the day we kiss my lips
3
4 light as a feather
*####@localhost ~$*

Here is my code:

#include <stdio.h>

int main(int argc, char *argv[]) {
    FILE *fp;
    int c, n;
    n = 1;
    for (int i = 1; i < argc; i++) {
        if (argc < 2) 
            fp = stdin; 
        else
            fp = fopen(argv[i], "r"); 
        c = getc(fp); 
        printf("%d ", n);
        while (c != EOF) { 
            putc(c, stdout); 
            if (c == '\n')
                n++, printf("%d ", n);
            c = getc(fp);
        }
        fclose(fp);
    }
    return 0;
}

Do not write printf("%d ", n); when you do not know if there is the next line. Or, otherwise, do printf("%d ", n); only on the beginning of the file and after a newline when you know there is a next char.

#include <stdbool.h>  // for bool, true, false
  

  bool previous_character_was_a_newline = true;
  while ((c = getc(fp)) != EOF) { 
     if (previous_character_was_a_newline) {
          previous_character_was_a_newline = false;
          printf("%d ", n);
     }
     putc(c, stdout); 
     if (c == '\n') {
        n++;
        previous_character_was_a_newline = true;
     }
  }

Do not write code like n++, printf("%d ", n); , it will be confusing. Strongly prefer:

     if (c == '\n') {
        n++;
        printf("%d ", n);
     }

Your implementation outputs the line number before the first line and after each newline, including the one at the end of the file. This causes an extra line number to appear at the end of the file.

Let's define the output more precisely:

  • you want the line number at the beginning of each line
  • do you want the line counter to reset to 1 when a new file is read? I assume no, but cat -n does.
  • do you want to output an extra newline at the end of a non empty file that does not end with a newline? I assume yes but cat -n does not.

Here is a modified version where the answer is no for the first question and yes for the second:

#include <stdio.h>

int output_file(FILE *fp, int line) {
    int c, last = '\n';
    while ((c = getc(fp)) != EOF) {
        if (last == '\n') {
            printf("%d\t", line++);
        }
        putchar(c);
        last = c;
    }
    /* output newline at end of file if non empty and no trailing newline */
    if (last != '\n') {
        putchar('\n');
    }
    return line;
}

int main(int argc, char *argv[]) {
    int n = 1;

    if (argc < 2) {
        n = output_file(stdin, n);
    } else {
        for (int i = 1; i < argc; i++) {
            FILE *fp = fopen(argv[i], "r");
            if (fp == NULL) {
                perror(argv[i]);
            } else {
                n = output_file(fp, n);
                fclose(fp);
            }
        }
    }
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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