2

I'm trying to read a txt file containing strings of 1s and 0s and print it out in the manner below. I tried my code a couple of months ago and it worked fine in reading the text file. Now when I tried it, it outputs something really strange. Also I tried changing the directory of the file to a non-existant file but it still outputs the same thing when it should've quit the program immediately. Please help!

The content of txt file:-

10000001
01110111
01111111
01111010
01111010
01110111

Expected output:-

data_in<=24'b10000001;
#10000;

Real output:-

data_in<=24'b(some weird symbol that changes everytime I recompile);
#10000;

My code:-

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (int argc, char *argv[])
{
    int i, j;
    j = 0;
    char words[50];
    FILE *fp;
    fp = fopen (argv[1], "r");

    if (fp == NULL) {
        printf ("Can't open file\n");
    }

    while (feof (fp) == 0) {
        fscanf (fp, "%s", words);
        printf ("data_in<=24'b%s\n", words);
        printf ("#10000\n");
    }

    fclose (fp);
    system ("PAUSE");
    return 0;
}

The input argument is the following:-

"C:\Users\Beanz\Documents\MATLAB\football frame\frame1.txt"
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • at first glance the program looks ok – bolov Jun 30 '15 at 20:27
  • Better use `fgets` to read single line. – i486 Jun 30 '15 at 20:27
  • Here seems to be an answer: http://stackoverflow.com/questions/3463426/in-c-how-should-i-read-a-text-file-and-print-all-strings – Michael Blankenship Jun 30 '15 at 20:27
  • 5
    don't use `feof`, try using `while(fgets(line, fr) != NULL)` instead – Olivier Poulin Jun 30 '15 at 20:28
  • 3
    [why is while(!feof(file)) always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Alex Celeste Jun 30 '15 at 20:28
  • @Leushenko: Just taking the headline: that is incorrect. If you have read from the file already, this might very well be the right way to use `feof`. – too honest for this site Jun 30 '15 at 20:33
  • Works as advertised, I fail to see the problem. You may want to stop the program when the file cannot be opened. As it is, it continues, which may explain your weird output (in combination with a non existing input). (Where did the `;` in your sample output come from?) – Jongware Jun 30 '15 at 20:34
  • Thanks for your input guys! Let's not forget the code worked a few months ago. It somehow doesn't work now. Do you think rebooting the computer will fix it? @Jongware my bad.. There shouldn't be `;` there... Did u test the code and it worked? I'm starting to think there's something wrong with my computer... IS that even possible? – Hiroshi Nakamura Jun 30 '15 at 20:39
  • I did test it, with and without an existing file. Both `clang` and `gcc` complain about unused variables (I use `-Wall -Wextra`), but valgrind has nothing to complain about. – Jongware Jun 30 '15 at 20:40
  • @Jongware the unused variables are the `int i,j` at the top which I forgot to comment out.. Other than that I trust the code works just fine right? Thank you so much!! I really appreciate it! I'm gonna try it out on a friend's computer. – Hiroshi Nakamura Jun 30 '15 at 20:46
  • 2
    when fopen() fails, exit the program. Do not continue the execution. – user3629249 Jun 30 '15 at 21:06
  • the compiler also outputs a warning message about unused function parameters:argc. Suggest always compiling with all warnings enabled. For gcc, at a minimum use, '-Wall -Wextra -pedantic' When the argv[] parameter is expected to contain some command line parameters, always check argc to assure such parameter(s) actually exist, and if they required number of parameters do not exist, display a 'usage' message and exit – user3629249 Jun 30 '15 at 21:10
  • 1
    when calling fscanf() and related family of functions, when the format string has a %s input/format specifier, always limit the total number of input characters so the input buffer is not overrun. One way is to include a 'length' modifier (in this case 49 as that allows for the NUL character appended by fscanf()) I.E. '%49s' otherwise, the input buffer can be overrun, resulting in undefined behaviour which can/will lead to a seg fault event. – user3629249 Jun 30 '15 at 21:21
  • @Jongware:- Hello... I tried running my code on a different computer and it worked just fine with text files with less than 1000 lines. However when I tried running the code on a text file that has 84480 lines (2.5MB) it outputs `data_in<=24'b(some weird symbol that changes everytime I recompile); #10000;` Is there a limit to how much lines my code can work on? Is there a way I can work around this? – Hiroshi Nakamura Jul 01 '15 at 02:59
  • 2
    @HiroshiNakamura, you have gotten a lot of good advice about necessary improvements to your program, but you give no indication of having tried to implement any of it. Before you speculate about other things that you suppose *might* be wrong with your program, you should fix the things that definitely *are* wrong with it. That it happens now or in the past to produce the expected result for some inputs does not prove it correct. – John Bollinger Jul 01 '15 at 03:20

2 Answers2

1

Read each line one by one with getline(3) -if available- or with fgets (you'll then need a large enough line buffer, at least 256 bytes), then parse each line buffer appropriately, using sscanf (the %n might be useful, and you should test the scanned item count result of sscanf) or other functions (e.g. strtok, strtol, etc...)

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

Remember that 'feof()' is only set AFTER trying to read PAST the end of the file, not when at the end of the file.

So the final iteration through the loop will try to read/process data that contains trash or prior contents.

Always check the returned value from 'fscanf()' before trying to use the associated data.

strongly suggest

eliminate the call to feof() and use the fscanf() to control the loop

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • Hello.. Thanks for the suggestion. I tried running my code on a different computer and it worked just fine with text files with less than 1000 lines. However when I tried running the code on a text file that has 84480 lines (2.5MB) it outputs `data_in<=24'b(some weird symbol that changes everytime I recompile); #10000;` Is there a limit to how much lines my code can work on? – Hiroshi Nakamura Jul 01 '15 at 02:57
  • 1
    The size of the input file should have no effect on your program operation. After all, your program only knows about 1 line/input at a time. – user3629249 Jul 01 '15 at 03:38