3
\$\begingroup\$

This will read 5 lines into a file from stdin, then print all the lines except the second one.

I used an array because I'm not sure how to do dynamic memory allocation.

#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 1024

void write_to_file(const char *s);
void print_file(const char *s);


int main(void){
    const char file_name[] = "text";
    write_to_file(file_name);
    print_file(file_name);

    return 0;
}

void write_to_file(const char *s){
    FILE *in_file;
    if((in_file = fopen(s, "w")) == NULL){
        perror(s);
        exit(EXIT_FAILURE);
    }

    char buffer[MAX_SIZE];
    for(int i = 0; i < 5; ++i){
        fgets(buffer, sizeof(buffer), stdin);
        fputs(buffer, in_file);
    }

    fclose(in_file);
}

void print_file(const char *s){
    FILE *in_file;
    if((in_file = fopen(s, "r")) == NULL){
        perror(s);
        exit(EXIT_FAILURE);
    }
    int c;
    int flag = 0;
    while((c = fgetc(in_file)) != EOF){
        printf("%c", c);
        if((flag == 0) && (c == '\n')){
            while((c = fgetc(in_file)) != '\n'){
                /*skip the second line*/
            }
            flag = 1;
        }
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ Interesting. But where is a question? \$\endgroup\$
    – pgs
    Apr 20, 2017 at 11:51
  • \$\begingroup\$ @pgs Write 5 lines to a file and print them with the exception of the second line. Was that not obvious? \$\endgroup\$
    – user127566
    Apr 20, 2017 at 12:14
  • \$\begingroup\$ it's the description of what this peace of code is doing. But there is nothing about an actual problem you have faced. \$\endgroup\$
    – pgs
    Apr 20, 2017 at 12:22
  • 5
    \$\begingroup\$ @pgs We're on Codereview. \$\endgroup\$
    – user127566
    Apr 20, 2017 at 12:34

2 Answers 2

4
\$\begingroup\$

You have the right idea in write_to_file(), but print_file() is awkward.

There is no need to work a character at a time in print_file(). You can read a line at a time using fgets(buffer, sizeof(buffer), in_file).

Avoid flag variables. Here, you could use a for loop to track the line number instead.

char buffer[MAX_SIZE];
for (int i = 0; fgets(buffer, sizeof(buffer), in_file) != EOF; ++i) {
    if (i != 1) puts(buffer);
}
\$\endgroup\$
5
  • \$\begingroup\$ Only problem with working with "lines" as opposed to chars, is if a "line" exceeds 1024 chars in length. (You can check for that, but if you know and/or control the data, it might not be worth the trouble to handle that case.) \$\endgroup\$
    – cHao
    Apr 20, 2017 at 15:27
  • \$\begingroup\$ @cHao That's true, but write_to_file() has the same weakness with long lines. It's unfortunate that the C standard does not include the getline() function of GNU libc. \$\endgroup\$ Apr 20, 2017 at 16:41
  • \$\begingroup\$ Here's hoping... \$\endgroup\$
    – cHao
    Apr 20, 2017 at 16:52
  • \$\begingroup\$ Why avoid flag variables? \$\endgroup\$
    – user127566
    Apr 20, 2017 at 17:21
  • \$\begingroup\$ For one thing, a variable whose name is flag tells me little about what its purpose is. For another, code that has flag variables can almost always be better expressed without them. It's hard to explain; you should just look at an overwhelming number of examples. \$\endgroup\$ Apr 21, 2017 at 3:43
3
\$\begingroup\$

Insure code easily reflects the "contract"

C program to write 5 lines to a file then print the lines except the second line

Given the above as the coding goal, consider it important that on code review (what this site does), it should be easily discernible that the goals are met.

I did not see that easy discernment in OP's code especially with the "except the second line" requirement.

Improved example:

#define WRITE_LINE_COUNT 5
#define PRINT_LINE_EXCEPT 2

....
// for(int i = 0; i < 5; ++i){
for(int i = 0; i < WRITE_LINE_COUNT; ++i){
    fgets(buffer, sizeof buffer, stdin);
    fputs(buffer, in_file);
}

...
unsigned long line = 1;
while((c = fgetc(in_file)) != EOF){
  if (line != PRINT_LINE_EXCEPT) {
    printf("%c", c);
  }
  if (c == '\n') line++;
}

Also best to check the results of fgets() and fgetc() against NULL and EOF, respectively.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.