1

This is my code and what am I trying to do is to fscanf from file that is structured like this:

Tom Veri 1234567890 HJA
Peter Schmit 9874561230 ABA
Jhon Smart 0192837465 DPA
Harry Tompson 0912354876 PHA

And after compiling my output is weird why that happens: Code is below

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

int nOfLines(FILE* file);

struct inputAbc
{
    char ime[20+1];
    char prezime[20+1];
    char jmbg[20+1];
    char sign[3+1];
};

int main()
{
    int nLines, i;
    FILE* input = NULL;
    FILE* output;
    struct inputAbc model_arr[10];

    input = fopen("input.txt", "r");
    output = fopen("output.txt", "w");
    nLines = nOfLines(input);
    //printf("%d\n", nLines+1);

    for(i = 0; i < nLines+1; i++)
    {
        fscanf(input ,"%s %s %s %s", 
        model_arr[i].ime, model_arr[i].prezime, 
        model_arr[i].jmbg, model_arr[i].sign);
    }
    for(i = 0; i < nLines+1; i++)
    {
        fprintf(output, 
            "ime: %s\nprezime: %s\njmbg: %s\nznakovlje: %s\n\n", 
            model_arr[i].ime, model_arr[i].prezime,
            model_arr[i].jmbg, model_arr[i].sign);
    }

    return 0;
}

int nOfLines(FILE *file)
{
    int lines = 0;
    int index;
    while(!feof(file))
    {
        index = fgetc(file);
        if(index == '\n')
            lines++;
    }
    return lines;
}
Ben Rhys-Lewis
  • 3,118
  • 8
  • 34
  • 45
Dongilica
  • 73
  • 7
  • 1
    *my output is weird*... please could you be specific? – lurker Jan 03 '20 at 14:16
  • ime: H. prezime: jmbg: znakovlje: ime: prezime: ‰ jmbg: znakovlje: @ ime: prezime: N jmbg: i znakovlje: ime: prezime: jmbg: znakovlje: Áţ˙˙Ĺţ˙˙¶˙˙˙e – Dongilica Jan 03 '20 at 14:17
  • it looks like this sry for no tabs or enters – Dongilica Jan 03 '20 at 14:17
  • 1
    You should edit your question and show the output there where you can format it properly. – lurker Jan 03 '20 at 14:17
  • how do you mean there are 4 lines in text show and program counts 4 – Dongilica Jan 03 '20 at 14:19
  • Whoops sorry, I didn't read the code carefully enough. My mistake. – lurker Jan 03 '20 at 14:20
  • 2
    Where do you think the internals of the file pointer `input` in `main` refers after the `nOfLines` function finishes ? Hint: It is *not* the beginning of the file. Notable: This entire thing would be circumvented if you actually checked the return value of your `fscanf` call (which will tell you the number of *successful* arguments parsed) rather than assuming it just always works. Assumption: the mother of all... – WhozCraig Jan 03 '20 at 14:21
  • 2
    You probably don't want `while(!feof(file))`. You should just check `while ((input = fgetc(input)) != EOF)`. And as WhozCraig indicates, you need to reset your input file pointer to the beginning of the file. – lurker Jan 03 '20 at 14:21
  • 2
    _[Why using while(!feof(file)) is wrong](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong)_ – ryyker Jan 03 '20 at 14:23
  • so i need to do rewind(fp) after that? – Dongilica Jan 03 '20 at 14:23
  • 1
    As far as I can see, nOfLines is worthless. You read the file until EOF anyway, so why not just do that from inception, stuffing results in your array and being careful not to overrun its boundaries. You can just as easily count lines while reading them, thereby single-passing the entire read operation. – WhozCraig Jan 03 '20 at 14:25
  • 1
    You could do `rewind(input)`. But, you can skip using `nOfLines`. Look at the manual page for `fscanf` and particularly at what it's return value is. Use that information instead. – lurker Jan 03 '20 at 14:26
  • Thank you guys its ok now you saved me a lot of frustration <3 – Dongilica Jan 03 '20 at 14:26
  • is something wrong with rewind cuz its working now when i have done it.... does it affect code on big scale somehow – Dongilica Jan 03 '20 at 14:28
  • Is your objective to learn to use `scanf`?, or is it simply to read the contents of a file. Because _[using scanf properly is one of the most complicated things to do in C.](http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html). (look at rule 0.) – ryyker Jan 03 '20 at 14:28

1 Answers1

2

the following proposed code:

  1. cleanly compiles
  2. performs the desired functionality
  3. produces the desired output
  4. eliminates some of the 'magic' numbers
  5. eliminates unneeded variables
  6. is commented to assist OP in understanding the code
  7. uses 'max character' modifiers in the fscanf() to avoid any possibility of a buffer overflow and the resulting undefined behavior
  8. eliminates: #include <string.h> because none of the associated functionality is used in the posted code
  9. properly cleans up (by closing open files) before exiting.
  10. properly checks for I/O errors for fopen() and fscanf()
  11. used size_t for variables i and j as they can never be less than 0

and now, the proposed code:

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


struct inputAbc
{
    char ime[20+1];
    char prezime[20+1];
    char jmbg[20+1];
    char sign[3+1];
};

#define MAX_LINES    10


int main( void )
{
    FILE* input  = NULL;
    FILE* output = NULL;
    struct inputAbc model_arr[ MAX_LINES ];

    if( (input = fopen("input.txt", "r")) == NULL )
    {
        perror( "fopen to read 'input.txt' failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen for input successful
    if( (output = fopen("output.txt", "w") ) == NULL )
    {
        perror( "fopen to write 'output.txt' failed" );
        fclose( input );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen for output successful
    size_t i;  // file global scope since needed in next code block
    for( i = 0; i < MAX_LINES; i++ )
    { 
        if( fscanf(input ,"%20s %20s %20s %3s", 
                model_arr[i].ime, 
                model_arr[i].prezime, 
                model_arr[i].jmbg, 
                model_arr[i].sign) != 4 )
        {
            break;
        }
    }

    for( size_t j = 0; j < i; j++ )
    {
        fprintf(output, 
            "ime: %s\nprezime: %s\njmbg: %s\nznakovlje: %s\n\n", 
            model_arr[j].ime, 
            model_arr[j].prezime,
            model_arr[j].jmbg, 
            model_arr[j].sign);
    }

    fclose( input );
    fclose( output );

    return 0;
}
user3629249
  • 16,402
  • 1
  • 16
  • 17