sorry i'm new at c
i want to read these data from txt file.
A 7
c 5
y 6
U 9
j 4
Z 3
z 5
0

here is my code

 while(feof(input)==0){
        char c;
        int num;
        fscanf(input,"%c%d",&c,&num);
        printf("%c:%d\n",c,num);
}

but result in console is not same as txt file
the result is

Open file complete
A:7

:7
c:5

:5
y:6

:6
U:9

:9
j:4

:4
Z:3

:3
z:5

:0

my code is correct, isn't it?

I don't think its necessary to take input as character and as number. Take it as a whole character array.

 FILE *fp = fopen(filename,"r");

 while( fscanf ( fp,"%s", text ) > 0 )
 {
      printf("%s", text);
 }

Try this out.

For more information about fscanf() functions, check this out.

Edited 4 Years Ago by np complete

but result in console is not same as txt file

The line break after each number in your file is a character too. scanf() first reads 'A' and 7 correctly, then prints them. Next it reads '\n' as the character part, but fails the integer part because 'c' isn't a valid decimal digit. You don't do any error checking, so the new character ('\n') and the old integer (7) are printed.

You can easily prove that this is happening by also printing the return value of scanf(). scanf() returns the number of successful conversions, or EOF if no conversions took place, so it should always print 2 or EOF:

while (feof(input)==0){
    char c;
    int num;
    printf("scanf() returned %d\n", fscanf(input,"%c%d",&c,&num));
    printf("%c:%d\n",c,num);
}

But it doesn't. It prints this:

scanf() returned 2
A:7
scanf() returned 1

:7
scanf() returned 2
c:5
scanf() returned 1

:5
...

The fix is to correctly recognize the presence of the newline character and handle it.

On a side note, feof() is inappropriate for controlling a loop because it only returns true after you attempt to read input and fail. Unless there's also a test within the loop body to stop processing of failed input on end-of-file, you'll end up processing the last record of a file twice.

my code is correct, isn't it?

If running the code does not give the required output, then either the input or the code is obviously not correct.

The %c format specifier does not skip whitespace, so the 2nd time the fscanf is executed, c will contain the end-of-line character '\n'. The %d format specifier stops at the first character that does not fit in an integer, which is the character c on the second line of input. num will still contain the number 7 of the previous read.

So how can I skip '\n'

An easy and somewhat obscure way is to prepend your format string with whitespace. The %c specifier doesn't trim leading whitespace like most of the other specifiers, but literal whitespace in a format string tells scanf() to read and discard all whitespace. So you can get the same trim effect like so:

while(feof(input)==0){
    char c;
    int num;
    fscanf(input," %c%d",&c,&num);
    printf("%c:%d\n",c,num);
}

And to fully handle the sentinel at the end of the file, add a conditional around your output:

while(feof(input)==0){
    char c;
    int num;

    if (fscanf(input," %c%d",&c,&num) == 2)
        printf("%c:%d\n",c,num);
}

Finally, to avoid the feof() problem and also handle the sentinel in one swell foop, use the result of fscanf() as your loop condition:

char c;
int num;

while (fscanf(input, " %c%d", &c, &num) == 2)
    printf("%c:%d\n", c, num);
This article has been dead for over six months. Start a new discussion instead.