fscanf returns 3 instead of -1 (EOF) at the end of the file












0















So there's a file I'm using fscanf() in. I've set a condition in my code that when (fscanf(...) == EOF, the program needs to break out of the function I'm currently in. The thing is, this condition is never satisfied in any of the cases where there's no more lines of text in the file. EOF is always -1, whereas fscanf(...) returns 4 each time there's a line of code, and 3 when there's nothing left for it to search through (instead of -1). If I add a line of code similar to the other ones, I will simply get one more instance of fscanf() returning 4, and then again, it'll give me a 3.



What could possibly be the issue? Thank you in advance!



Sample text file content:



CHRISTOU GIORGOS,140,VAS. OLGAS 112



MALAKOU MALAKOS,150,DRAS. BAGAS 12



TSIKOU GIJRAN,140,JABS. DRALGAS 1



TSIKOU BIRBAN,140,JABS. DRALGAS 1



DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62



FOX SIN,40,BAN. NINJA 1



Code:



#include <stdio.h>
#define M 100

typedef struct {
char name[30];
int apousies;
} studentT;

void readInput (FILE* infile, studentT students, int *pApousies, int *pStudents);


int main()
{
char inputfilename[30];
FILE* infile;

while (1) {
printf("Input file name :");
gets(inputfilename);

infile = fopen(inputfilename, "r");

if (infile != NULL) break;
printf("Cannot open input file %s. Try again.n", inputfilename);
}

studentT students[M];
int numberOfStudents = 0, numberOfApousies = 0;
readInput(infile, students, &numberOfApousies, &numberOfStudents);
fclose(infile);
return 0;
}

void readInput (FILE* infile, studentT students, int *pApousies, int *pStudents)
{
int nscan, apousies, studcount, apouscount, line;
char name[30], comments[68], termch;

line = 0;
while (1)
{
nscan = fscanf(infile, "%30[^,], %d, %68[^n]%c", name, &apousies, comments, &termch);
/* printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);
printf("%dn", nscan);
printf("%dn", EOF);*/
if (nscan == EOF) break;
line++;

if (nscan != 4 || termch != 'n')
{
printf("Error in line %d. Program terminationn", line);
exit(1);
}
}
}









share|improve this question




















  • 2





    (fscanf(...) == EOF the program needs to break out of the function --> That is a weak test. Better to test against the one desired return - perhaps like (fscanf(...) != 4. Please post a Minimal, Complete, and Verifiable example.

    – chux
    Jan 2 at 23:42













  • Post definition of studentT. The post is better, yet not complete enough to compile.

    – chux
    Jan 2 at 23:44











  • I wasn't sure as to which parts of the code were relevant to the question. I hope this helps. Thanks again.

    – Leet
    Jan 2 at 23:49






  • 1





    Please provide a Minimal, Complete, and Verifiable example showing exactly how you are using fscanf(), particularly your actual format string

    – Remy Lebeau
    Jan 2 at 23:51













  • Note that your code is strange. You pass pApousies as a parameter to the function readInput, and don't use it. The you declare a local variable apousies and use it in the call to fscanf. Your test of nscan == EOF looks ok to me.

    – bruceg
    Jan 3 at 0:05
















0















So there's a file I'm using fscanf() in. I've set a condition in my code that when (fscanf(...) == EOF, the program needs to break out of the function I'm currently in. The thing is, this condition is never satisfied in any of the cases where there's no more lines of text in the file. EOF is always -1, whereas fscanf(...) returns 4 each time there's a line of code, and 3 when there's nothing left for it to search through (instead of -1). If I add a line of code similar to the other ones, I will simply get one more instance of fscanf() returning 4, and then again, it'll give me a 3.



What could possibly be the issue? Thank you in advance!



Sample text file content:



CHRISTOU GIORGOS,140,VAS. OLGAS 112



MALAKOU MALAKOS,150,DRAS. BAGAS 12



TSIKOU GIJRAN,140,JABS. DRALGAS 1



TSIKOU BIRBAN,140,JABS. DRALGAS 1



DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62



FOX SIN,40,BAN. NINJA 1



Code:



#include <stdio.h>
#define M 100

typedef struct {
char name[30];
int apousies;
} studentT;

void readInput (FILE* infile, studentT students, int *pApousies, int *pStudents);


int main()
{
char inputfilename[30];
FILE* infile;

while (1) {
printf("Input file name :");
gets(inputfilename);

infile = fopen(inputfilename, "r");

if (infile != NULL) break;
printf("Cannot open input file %s. Try again.n", inputfilename);
}

studentT students[M];
int numberOfStudents = 0, numberOfApousies = 0;
readInput(infile, students, &numberOfApousies, &numberOfStudents);
fclose(infile);
return 0;
}

void readInput (FILE* infile, studentT students, int *pApousies, int *pStudents)
{
int nscan, apousies, studcount, apouscount, line;
char name[30], comments[68], termch;

line = 0;
while (1)
{
nscan = fscanf(infile, "%30[^,], %d, %68[^n]%c", name, &apousies, comments, &termch);
/* printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);
printf("%dn", nscan);
printf("%dn", EOF);*/
if (nscan == EOF) break;
line++;

if (nscan != 4 || termch != 'n')
{
printf("Error in line %d. Program terminationn", line);
exit(1);
}
}
}









share|improve this question




















  • 2





    (fscanf(...) == EOF the program needs to break out of the function --> That is a weak test. Better to test against the one desired return - perhaps like (fscanf(...) != 4. Please post a Minimal, Complete, and Verifiable example.

    – chux
    Jan 2 at 23:42













  • Post definition of studentT. The post is better, yet not complete enough to compile.

    – chux
    Jan 2 at 23:44











  • I wasn't sure as to which parts of the code were relevant to the question. I hope this helps. Thanks again.

    – Leet
    Jan 2 at 23:49






  • 1





    Please provide a Minimal, Complete, and Verifiable example showing exactly how you are using fscanf(), particularly your actual format string

    – Remy Lebeau
    Jan 2 at 23:51













  • Note that your code is strange. You pass pApousies as a parameter to the function readInput, and don't use it. The you declare a local variable apousies and use it in the call to fscanf. Your test of nscan == EOF looks ok to me.

    – bruceg
    Jan 3 at 0:05














0












0








0








So there's a file I'm using fscanf() in. I've set a condition in my code that when (fscanf(...) == EOF, the program needs to break out of the function I'm currently in. The thing is, this condition is never satisfied in any of the cases where there's no more lines of text in the file. EOF is always -1, whereas fscanf(...) returns 4 each time there's a line of code, and 3 when there's nothing left for it to search through (instead of -1). If I add a line of code similar to the other ones, I will simply get one more instance of fscanf() returning 4, and then again, it'll give me a 3.



What could possibly be the issue? Thank you in advance!



Sample text file content:



CHRISTOU GIORGOS,140,VAS. OLGAS 112



MALAKOU MALAKOS,150,DRAS. BAGAS 12



TSIKOU GIJRAN,140,JABS. DRALGAS 1



TSIKOU BIRBAN,140,JABS. DRALGAS 1



DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62



FOX SIN,40,BAN. NINJA 1



Code:



#include <stdio.h>
#define M 100

typedef struct {
char name[30];
int apousies;
} studentT;

void readInput (FILE* infile, studentT students, int *pApousies, int *pStudents);


int main()
{
char inputfilename[30];
FILE* infile;

while (1) {
printf("Input file name :");
gets(inputfilename);

infile = fopen(inputfilename, "r");

if (infile != NULL) break;
printf("Cannot open input file %s. Try again.n", inputfilename);
}

studentT students[M];
int numberOfStudents = 0, numberOfApousies = 0;
readInput(infile, students, &numberOfApousies, &numberOfStudents);
fclose(infile);
return 0;
}

void readInput (FILE* infile, studentT students, int *pApousies, int *pStudents)
{
int nscan, apousies, studcount, apouscount, line;
char name[30], comments[68], termch;

line = 0;
while (1)
{
nscan = fscanf(infile, "%30[^,], %d, %68[^n]%c", name, &apousies, comments, &termch);
/* printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);
printf("%dn", nscan);
printf("%dn", EOF);*/
if (nscan == EOF) break;
line++;

if (nscan != 4 || termch != 'n')
{
printf("Error in line %d. Program terminationn", line);
exit(1);
}
}
}









share|improve this question
















So there's a file I'm using fscanf() in. I've set a condition in my code that when (fscanf(...) == EOF, the program needs to break out of the function I'm currently in. The thing is, this condition is never satisfied in any of the cases where there's no more lines of text in the file. EOF is always -1, whereas fscanf(...) returns 4 each time there's a line of code, and 3 when there's nothing left for it to search through (instead of -1). If I add a line of code similar to the other ones, I will simply get one more instance of fscanf() returning 4, and then again, it'll give me a 3.



What could possibly be the issue? Thank you in advance!



Sample text file content:



CHRISTOU GIORGOS,140,VAS. OLGAS 112



MALAKOU MALAKOS,150,DRAS. BAGAS 12



TSIKOU GIJRAN,140,JABS. DRALGAS 1



TSIKOU BIRBAN,140,JABS. DRALGAS 1



DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62



FOX SIN,40,BAN. NINJA 1



Code:



#include <stdio.h>
#define M 100

typedef struct {
char name[30];
int apousies;
} studentT;

void readInput (FILE* infile, studentT students, int *pApousies, int *pStudents);


int main()
{
char inputfilename[30];
FILE* infile;

while (1) {
printf("Input file name :");
gets(inputfilename);

infile = fopen(inputfilename, "r");

if (infile != NULL) break;
printf("Cannot open input file %s. Try again.n", inputfilename);
}

studentT students[M];
int numberOfStudents = 0, numberOfApousies = 0;
readInput(infile, students, &numberOfApousies, &numberOfStudents);
fclose(infile);
return 0;
}

void readInput (FILE* infile, studentT students, int *pApousies, int *pStudents)
{
int nscan, apousies, studcount, apouscount, line;
char name[30], comments[68], termch;

line = 0;
while (1)
{
nscan = fscanf(infile, "%30[^,], %d, %68[^n]%c", name, &apousies, comments, &termch);
/* printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);
printf("%dn", nscan);
printf("%dn", EOF);*/
if (nscan == EOF) break;
line++;

if (nscan != 4 || termch != 'n')
{
printf("Error in line %d. Program terminationn", line);
exit(1);
}
}
}






c scanf eof






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 0:34









chux

84.3k874154




84.3k874154










asked Jan 2 at 23:35









LeetLeet

387




387








  • 2





    (fscanf(...) == EOF the program needs to break out of the function --> That is a weak test. Better to test against the one desired return - perhaps like (fscanf(...) != 4. Please post a Minimal, Complete, and Verifiable example.

    – chux
    Jan 2 at 23:42













  • Post definition of studentT. The post is better, yet not complete enough to compile.

    – chux
    Jan 2 at 23:44











  • I wasn't sure as to which parts of the code were relevant to the question. I hope this helps. Thanks again.

    – Leet
    Jan 2 at 23:49






  • 1





    Please provide a Minimal, Complete, and Verifiable example showing exactly how you are using fscanf(), particularly your actual format string

    – Remy Lebeau
    Jan 2 at 23:51













  • Note that your code is strange. You pass pApousies as a parameter to the function readInput, and don't use it. The you declare a local variable apousies and use it in the call to fscanf. Your test of nscan == EOF looks ok to me.

    – bruceg
    Jan 3 at 0:05














  • 2





    (fscanf(...) == EOF the program needs to break out of the function --> That is a weak test. Better to test against the one desired return - perhaps like (fscanf(...) != 4. Please post a Minimal, Complete, and Verifiable example.

    – chux
    Jan 2 at 23:42













  • Post definition of studentT. The post is better, yet not complete enough to compile.

    – chux
    Jan 2 at 23:44











  • I wasn't sure as to which parts of the code were relevant to the question. I hope this helps. Thanks again.

    – Leet
    Jan 2 at 23:49






  • 1





    Please provide a Minimal, Complete, and Verifiable example showing exactly how you are using fscanf(), particularly your actual format string

    – Remy Lebeau
    Jan 2 at 23:51













  • Note that your code is strange. You pass pApousies as a parameter to the function readInput, and don't use it. The you declare a local variable apousies and use it in the call to fscanf. Your test of nscan == EOF looks ok to me.

    – bruceg
    Jan 3 at 0:05








2




2





(fscanf(...) == EOF the program needs to break out of the function --> That is a weak test. Better to test against the one desired return - perhaps like (fscanf(...) != 4. Please post a Minimal, Complete, and Verifiable example.

– chux
Jan 2 at 23:42







(fscanf(...) == EOF the program needs to break out of the function --> That is a weak test. Better to test against the one desired return - perhaps like (fscanf(...) != 4. Please post a Minimal, Complete, and Verifiable example.

– chux
Jan 2 at 23:42















Post definition of studentT. The post is better, yet not complete enough to compile.

– chux
Jan 2 at 23:44





Post definition of studentT. The post is better, yet not complete enough to compile.

– chux
Jan 2 at 23:44













I wasn't sure as to which parts of the code were relevant to the question. I hope this helps. Thanks again.

– Leet
Jan 2 at 23:49





I wasn't sure as to which parts of the code were relevant to the question. I hope this helps. Thanks again.

– Leet
Jan 2 at 23:49




1




1





Please provide a Minimal, Complete, and Verifiable example showing exactly how you are using fscanf(), particularly your actual format string

– Remy Lebeau
Jan 2 at 23:51







Please provide a Minimal, Complete, and Verifiable example showing exactly how you are using fscanf(), particularly your actual format string

– Remy Lebeau
Jan 2 at 23:51















Note that your code is strange. You pass pApousies as a parameter to the function readInput, and don't use it. The you declare a local variable apousies and use it in the call to fscanf. Your test of nscan == EOF looks ok to me.

– bruceg
Jan 3 at 0:05





Note that your code is strange. You pass pApousies as a parameter to the function readInput, and don't use it. The you declare a local variable apousies and use it in the call to fscanf. Your test of nscan == EOF looks ok to me.

– bruceg
Jan 3 at 0:05












1 Answer
1






active

oldest

votes


















4















fscanf returns 3 instead of -1 (EOF) at the end of the file




Because the last line lacks a 'n'.





OP's code "works" with the "tmp.txt" the below code makes.



fscanf() is hard to use right. Easier to code and debug with fgets(). Discussion follows.





"%30[^,]" allows too much for char name[30]. Use char name[30+1] or "%29[^,]"



OP's approach can readily fail with seemingly minor parsing problems such as a missing 'n' on the last line. After such a failure, recovery is extraordinary difficult with fscanf()



Debug: Importantly, the below print should not be attempted until code insures nscan >= 4



if (nscan >= 4) // add
printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);




Instead, use fgets(). With line orientated data, this really is the best first step.



fscanf() is challenging to use and cope with errors. Far simpler to read a line with fgets() and then parse.



Using " %n" is a nice way to detect if all the line parsed.



#include <stdio.h>
#include <stdlib.h>
#define M 100

typedef struct {
char name[30];
int apousies;
} studentT;

void readInput(FILE* infile, studentT students, int *pApousies,
int *pStudents) {
(void) students;
(void) pApousies;
(void) pStudents;
int line = 0;
char buf[200];
while (fgets(buf, sizeof buf, infile)) {
int apousies;
char name[30], comments[68];
int n = 0;

line++;
sscanf(buf, " %29[^,],%d , %67[^n] %n", name, &apousies, comments, &n);
if (n == 0 || buf[n]) {
fprintf(stderr, "Error in line %d <%s>. Program terminationn", line, buf);
exit(1);
}
printf("Success %d <%s> %d <%s>n", line, name, apousies, comments);
}
}


Sample use



int main() {
FILE *f = fopen("tmp.txt", "w");
fputs("CHRISTOU GIORGOS,140,VAS. OLGAS 112n"
"MALAKOU MALAKOS,150,DRAS. BAGAS 12n"
"TSIKOU GIJRAN,140,JABS. DRALGAS 1n"
"TSIKOU BIRBAN,140,JABS. DRALGAS 1n"
"DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62n"
"FOX SIN,40,BAN. NINJA 1n", f);
fclose(f);

f = fopen("tmp.txt", "r");
studentT st[M];
readInput(f, st, NULL, NULL);
fclose(f);
}


Output



Success 1 <CHRISTOU GIORGOS> 140 <VAS. OLGAS 112>
Success 2 <MALAKOU MALAKOS> 150 <DRAS. BAGAS 12>
Success 3 <TSIKOU GIJRAN> 140 <JABS. DRALGAS 1>
Success 4 <TSIKOU BIRBAN> 140 <JABS. DRALGAS 1>
Success 5 <DELHDHMHTRIOU SPYROS> 50 <SPEED. BAGAS 62>
Success 6 <FOX SIN> 40 <BAN. NINJA 1>





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54014577%2ffscanf-returns-3-instead-of-1-eof-at-the-end-of-the-file%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4















    fscanf returns 3 instead of -1 (EOF) at the end of the file




    Because the last line lacks a 'n'.





    OP's code "works" with the "tmp.txt" the below code makes.



    fscanf() is hard to use right. Easier to code and debug with fgets(). Discussion follows.





    "%30[^,]" allows too much for char name[30]. Use char name[30+1] or "%29[^,]"



    OP's approach can readily fail with seemingly minor parsing problems such as a missing 'n' on the last line. After such a failure, recovery is extraordinary difficult with fscanf()



    Debug: Importantly, the below print should not be attempted until code insures nscan >= 4



    if (nscan >= 4) // add
    printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);




    Instead, use fgets(). With line orientated data, this really is the best first step.



    fscanf() is challenging to use and cope with errors. Far simpler to read a line with fgets() and then parse.



    Using " %n" is a nice way to detect if all the line parsed.



    #include <stdio.h>
    #include <stdlib.h>
    #define M 100

    typedef struct {
    char name[30];
    int apousies;
    } studentT;

    void readInput(FILE* infile, studentT students, int *pApousies,
    int *pStudents) {
    (void) students;
    (void) pApousies;
    (void) pStudents;
    int line = 0;
    char buf[200];
    while (fgets(buf, sizeof buf, infile)) {
    int apousies;
    char name[30], comments[68];
    int n = 0;

    line++;
    sscanf(buf, " %29[^,],%d , %67[^n] %n", name, &apousies, comments, &n);
    if (n == 0 || buf[n]) {
    fprintf(stderr, "Error in line %d <%s>. Program terminationn", line, buf);
    exit(1);
    }
    printf("Success %d <%s> %d <%s>n", line, name, apousies, comments);
    }
    }


    Sample use



    int main() {
    FILE *f = fopen("tmp.txt", "w");
    fputs("CHRISTOU GIORGOS,140,VAS. OLGAS 112n"
    "MALAKOU MALAKOS,150,DRAS. BAGAS 12n"
    "TSIKOU GIJRAN,140,JABS. DRALGAS 1n"
    "TSIKOU BIRBAN,140,JABS. DRALGAS 1n"
    "DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62n"
    "FOX SIN,40,BAN. NINJA 1n", f);
    fclose(f);

    f = fopen("tmp.txt", "r");
    studentT st[M];
    readInput(f, st, NULL, NULL);
    fclose(f);
    }


    Output



    Success 1 <CHRISTOU GIORGOS> 140 <VAS. OLGAS 112>
    Success 2 <MALAKOU MALAKOS> 150 <DRAS. BAGAS 12>
    Success 3 <TSIKOU GIJRAN> 140 <JABS. DRALGAS 1>
    Success 4 <TSIKOU BIRBAN> 140 <JABS. DRALGAS 1>
    Success 5 <DELHDHMHTRIOU SPYROS> 50 <SPEED. BAGAS 62>
    Success 6 <FOX SIN> 40 <BAN. NINJA 1>





    share|improve this answer






























      4















      fscanf returns 3 instead of -1 (EOF) at the end of the file




      Because the last line lacks a 'n'.





      OP's code "works" with the "tmp.txt" the below code makes.



      fscanf() is hard to use right. Easier to code and debug with fgets(). Discussion follows.





      "%30[^,]" allows too much for char name[30]. Use char name[30+1] or "%29[^,]"



      OP's approach can readily fail with seemingly minor parsing problems such as a missing 'n' on the last line. After such a failure, recovery is extraordinary difficult with fscanf()



      Debug: Importantly, the below print should not be attempted until code insures nscan >= 4



      if (nscan >= 4) // add
      printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);




      Instead, use fgets(). With line orientated data, this really is the best first step.



      fscanf() is challenging to use and cope with errors. Far simpler to read a line with fgets() and then parse.



      Using " %n" is a nice way to detect if all the line parsed.



      #include <stdio.h>
      #include <stdlib.h>
      #define M 100

      typedef struct {
      char name[30];
      int apousies;
      } studentT;

      void readInput(FILE* infile, studentT students, int *pApousies,
      int *pStudents) {
      (void) students;
      (void) pApousies;
      (void) pStudents;
      int line = 0;
      char buf[200];
      while (fgets(buf, sizeof buf, infile)) {
      int apousies;
      char name[30], comments[68];
      int n = 0;

      line++;
      sscanf(buf, " %29[^,],%d , %67[^n] %n", name, &apousies, comments, &n);
      if (n == 0 || buf[n]) {
      fprintf(stderr, "Error in line %d <%s>. Program terminationn", line, buf);
      exit(1);
      }
      printf("Success %d <%s> %d <%s>n", line, name, apousies, comments);
      }
      }


      Sample use



      int main() {
      FILE *f = fopen("tmp.txt", "w");
      fputs("CHRISTOU GIORGOS,140,VAS. OLGAS 112n"
      "MALAKOU MALAKOS,150,DRAS. BAGAS 12n"
      "TSIKOU GIJRAN,140,JABS. DRALGAS 1n"
      "TSIKOU BIRBAN,140,JABS. DRALGAS 1n"
      "DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62n"
      "FOX SIN,40,BAN. NINJA 1n", f);
      fclose(f);

      f = fopen("tmp.txt", "r");
      studentT st[M];
      readInput(f, st, NULL, NULL);
      fclose(f);
      }


      Output



      Success 1 <CHRISTOU GIORGOS> 140 <VAS. OLGAS 112>
      Success 2 <MALAKOU MALAKOS> 150 <DRAS. BAGAS 12>
      Success 3 <TSIKOU GIJRAN> 140 <JABS. DRALGAS 1>
      Success 4 <TSIKOU BIRBAN> 140 <JABS. DRALGAS 1>
      Success 5 <DELHDHMHTRIOU SPYROS> 50 <SPEED. BAGAS 62>
      Success 6 <FOX SIN> 40 <BAN. NINJA 1>





      share|improve this answer




























        4












        4








        4








        fscanf returns 3 instead of -1 (EOF) at the end of the file




        Because the last line lacks a 'n'.





        OP's code "works" with the "tmp.txt" the below code makes.



        fscanf() is hard to use right. Easier to code and debug with fgets(). Discussion follows.





        "%30[^,]" allows too much for char name[30]. Use char name[30+1] or "%29[^,]"



        OP's approach can readily fail with seemingly minor parsing problems such as a missing 'n' on the last line. After such a failure, recovery is extraordinary difficult with fscanf()



        Debug: Importantly, the below print should not be attempted until code insures nscan >= 4



        if (nscan >= 4) // add
        printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);




        Instead, use fgets(). With line orientated data, this really is the best first step.



        fscanf() is challenging to use and cope with errors. Far simpler to read a line with fgets() and then parse.



        Using " %n" is a nice way to detect if all the line parsed.



        #include <stdio.h>
        #include <stdlib.h>
        #define M 100

        typedef struct {
        char name[30];
        int apousies;
        } studentT;

        void readInput(FILE* infile, studentT students, int *pApousies,
        int *pStudents) {
        (void) students;
        (void) pApousies;
        (void) pStudents;
        int line = 0;
        char buf[200];
        while (fgets(buf, sizeof buf, infile)) {
        int apousies;
        char name[30], comments[68];
        int n = 0;

        line++;
        sscanf(buf, " %29[^,],%d , %67[^n] %n", name, &apousies, comments, &n);
        if (n == 0 || buf[n]) {
        fprintf(stderr, "Error in line %d <%s>. Program terminationn", line, buf);
        exit(1);
        }
        printf("Success %d <%s> %d <%s>n", line, name, apousies, comments);
        }
        }


        Sample use



        int main() {
        FILE *f = fopen("tmp.txt", "w");
        fputs("CHRISTOU GIORGOS,140,VAS. OLGAS 112n"
        "MALAKOU MALAKOS,150,DRAS. BAGAS 12n"
        "TSIKOU GIJRAN,140,JABS. DRALGAS 1n"
        "TSIKOU BIRBAN,140,JABS. DRALGAS 1n"
        "DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62n"
        "FOX SIN,40,BAN. NINJA 1n", f);
        fclose(f);

        f = fopen("tmp.txt", "r");
        studentT st[M];
        readInput(f, st, NULL, NULL);
        fclose(f);
        }


        Output



        Success 1 <CHRISTOU GIORGOS> 140 <VAS. OLGAS 112>
        Success 2 <MALAKOU MALAKOS> 150 <DRAS. BAGAS 12>
        Success 3 <TSIKOU GIJRAN> 140 <JABS. DRALGAS 1>
        Success 4 <TSIKOU BIRBAN> 140 <JABS. DRALGAS 1>
        Success 5 <DELHDHMHTRIOU SPYROS> 50 <SPEED. BAGAS 62>
        Success 6 <FOX SIN> 40 <BAN. NINJA 1>





        share|improve this answer
















        fscanf returns 3 instead of -1 (EOF) at the end of the file




        Because the last line lacks a 'n'.





        OP's code "works" with the "tmp.txt" the below code makes.



        fscanf() is hard to use right. Easier to code and debug with fgets(). Discussion follows.





        "%30[^,]" allows too much for char name[30]. Use char name[30+1] or "%29[^,]"



        OP's approach can readily fail with seemingly minor parsing problems such as a missing 'n' on the last line. After such a failure, recovery is extraordinary difficult with fscanf()



        Debug: Importantly, the below print should not be attempted until code insures nscan >= 4



        if (nscan >= 4) // add
        printf("onoma: %s apousies: %d sxolia: %s terma: %cn", name, apousies, comments, termch);




        Instead, use fgets(). With line orientated data, this really is the best first step.



        fscanf() is challenging to use and cope with errors. Far simpler to read a line with fgets() and then parse.



        Using " %n" is a nice way to detect if all the line parsed.



        #include <stdio.h>
        #include <stdlib.h>
        #define M 100

        typedef struct {
        char name[30];
        int apousies;
        } studentT;

        void readInput(FILE* infile, studentT students, int *pApousies,
        int *pStudents) {
        (void) students;
        (void) pApousies;
        (void) pStudents;
        int line = 0;
        char buf[200];
        while (fgets(buf, sizeof buf, infile)) {
        int apousies;
        char name[30], comments[68];
        int n = 0;

        line++;
        sscanf(buf, " %29[^,],%d , %67[^n] %n", name, &apousies, comments, &n);
        if (n == 0 || buf[n]) {
        fprintf(stderr, "Error in line %d <%s>. Program terminationn", line, buf);
        exit(1);
        }
        printf("Success %d <%s> %d <%s>n", line, name, apousies, comments);
        }
        }


        Sample use



        int main() {
        FILE *f = fopen("tmp.txt", "w");
        fputs("CHRISTOU GIORGOS,140,VAS. OLGAS 112n"
        "MALAKOU MALAKOS,150,DRAS. BAGAS 12n"
        "TSIKOU GIJRAN,140,JABS. DRALGAS 1n"
        "TSIKOU BIRBAN,140,JABS. DRALGAS 1n"
        "DELHDHMHTRIOU SPYROS,50,SPEED. BAGAS 62n"
        "FOX SIN,40,BAN. NINJA 1n", f);
        fclose(f);

        f = fopen("tmp.txt", "r");
        studentT st[M];
        readInput(f, st, NULL, NULL);
        fclose(f);
        }


        Output



        Success 1 <CHRISTOU GIORGOS> 140 <VAS. OLGAS 112>
        Success 2 <MALAKOU MALAKOS> 150 <DRAS. BAGAS 12>
        Success 3 <TSIKOU GIJRAN> 140 <JABS. DRALGAS 1>
        Success 4 <TSIKOU BIRBAN> 140 <JABS. DRALGAS 1>
        Success 5 <DELHDHMHTRIOU SPYROS> 50 <SPEED. BAGAS 62>
        Success 6 <FOX SIN> 40 <BAN. NINJA 1>






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 3 at 4:23

























        answered Jan 3 at 0:10









        chuxchux

        84.3k874154




        84.3k874154
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54014577%2ffscanf-returns-3-instead-of-1-eof-at-the-end-of-the-file%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Mossoró

            Error while reading .h5 file using the rhdf5 package in R

            Pushsharp Apns notification error: 'InvalidToken'