1

I'm new to C and I'm trying to open a file and print its content line by line to console.

The source code is attached along with a couple screen shots to show my situation. (The redded-out part contain my computer's directories and personal info). As you can see from the screenshot, the program prints "before" but not "after". Of course, neither does it print out anything from coc.txt.

I can't figure out why this is the case. Everything seems correct and I don't see any errors.

#include <stdio.h>
#include <stdlib.h> // For exit()

const int MAX_LINE_LENGTH = 300;
int main() {

    FILE  *inputFile;
    inputFile = fopen("coc.txt", "r");
    char lineRead[MAX_LINE_LENGTH];
    printf("before\n");
    while(!feof(inputFile)) {
        fgets(lineRead, MAX_LINE_LENGTH, inputFile);
        puts(lineRead);
    }
    fclose(inputFile);
    printf("after\n");

}   

console

screenshot of IDE

coc.txt

screenshot of text editor

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • 4
    Two things: First always check what [`fopen`](https://en.cppreference.com/w/c/io/fopen) returns. Secondly, please read [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) The first thing would solve the ***crash*** you're having. – Some programmer dude Jan 21 '19 at 05:11
  • sorry, how do I check what fopen returns? –  Jan 21 '19 at 05:14
  • 2
    As for a hint of your problem, when you run the program, its working directory (which is the root of all relative paths inside your program) is not what you think it is. The file can't be found plain and simple. – Some programmer dude Jan 21 '19 at 05:14
  • 2
    The relevant message is the one you didn't mention: `Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)`. That means your program is crashing because of an invalid memory access. – melpomene Jan 21 '19 at 05:14
  • 2
    `inputFile = fopen("coc.txt", "r"); if (!inputFile) { fprintf(stderr, "Can't open %s: %s\n", "coc.txt", strerror(errno)); exit(EXIT_FAILURE); }` (you also need to include `` and ``). What source are you learning C from? – melpomene Jan 21 '19 at 05:16
  • this was a professor's project but I got the code mostly from https://www.youtube.com/watch?v=8nIilb2kiSU –  Jan 21 '19 at 05:17
  • Maybe I didn't get what he mentioned correctly. –  Jan 21 '19 at 05:18
  • @loosethefoolsjuice Yeah, that's awful code in that video. – melpomene Jan 21 '19 at 05:28
  • @melpomene thanks for your help. now it's giving the error that "Can't open coc.txt: No such file or directory" Is the same folder as the source code the wrong directory to put the text file? –  Jan 21 '19 at 05:31
  • 1
    @loosethefoolsjuice Try putting the text file in the directory your IDE saves the final executable file. – Spikatrix Jan 21 '19 at 05:33
  • @Spikatrix it worked holy shit it was like that all along. thank you so much. –  Jan 21 '19 at 05:36
  • You have just learned an important lesson in C programming. I.E. always check the returned value from C library functions for error indications – user3629249 Jan 21 '19 at 05:57

2 Answers2

2

Here's a suggested alternative (not tested yet):

#include <stdio.h>

#define MAX_LINE_LENGTH 300
#define NULL 0

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

    FILE  *inputFile;
    char fname[MAX_LINE_LENGTH], lineRead[MAX_LINE_LENGTH];

    /* Get filename from cmd-line */
    if (argc != 2) {
        printf ("USAGE: progname <fname>\n");
        return 1;
    }

    /* Try to open file */
    if ((inputFile = fopen("coc.txt", "r")) == NULL) {
        perror("Could not open file");
        return 2;
    }

    /* Now read the file, and echo back a line at a time */
    printf("before...\n");
    while(fgets(lineRead, MAX_LINE_LENGTH, inputFile) != NULL) {
        printf ("%s", lineRead);
    }
    printf("\n...after\n");

    /* Cleanup and exit */
    fclose(inputFile);
    return 0;
}

Changes:

  1. Be sure to have a "return" from main ().

    In general, a graceful "return" from main() is preferred over a system call to "exit()".

  2. Read the input, then to check for EOF (fgets() == NULL).

  3. Make sure you've opened the file before reading.

  4. Rather than hard-coding the filename, we're reading it from the command line.

  5. Rather than puts() (which always appends a newline, regardless of whether the string already has a newline), we're using printf().

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • 3
    `return` is not function; it cannot be "called". An explicit `return` statement is not required in `main` (if you're using C99, which OP is because they're also using a VLA). If we're going for portability, `1` is not necessarily an error status. Your code adds empty lines to the output. There's nothing wrong with calling `exit`. – melpomene Jan 21 '19 at 05:21
  • 1
    @loosethefoolsjuice I'd say it works great now. Instead of crashing, your program now prints an error message and even says why it couldn't open the file: The file you've specified doesn't exist (at least not in the directory it's running in). For quick and dirty way to see where it's running, `#include ` and add `system("pwd");` to your `main` function. – melpomene Jan 21 '19 at 05:35
  • To fix the double spacing in the output, use `fputs(lineRead, stdout);` instead of `puts`. – melpomene Jan 21 '19 at 05:39
  • @melpomene - thank you for the notes. That's what I get for posting code without actually compiling/tesing it first ;) I made some changes earlier; I trust the OP is squared away with his remaining questions by now. – paulsm4 Jan 21 '19 at 06:21
  • Isn't an empty parameter list a deprecated feature? – Gerhardh Jan 21 '19 at 08:00
0

Make sure that the coc.txt file and the read.c files are in the same folder. I executed your original code and it works fine with VS 2017 on windows 10.

sri
  • 359
  • 2
  • 5