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?

Dani AI

Generated

The console output shows blank lines and repeated numbers because the code reads raw characters with %c (which does not skip whitespace). As and noted, the newline left in the stream becomes the next char and the integer conversion fails, leaving the previous int untouched. Also, using feof() to drive the loop hides read failures and can lead to processing the last record twice.

A more robust approach is to read complete lines and parse each line while always checking conversion return values. This keeps parsing local to one line, handles odd/malformed lines, and makes the sentinel (0) easy to detect. Example:

char line[128];

while (fgets(line, sizeof line, input)) {
    char key;
    int value;

    if (sscanf(line, " %c %d", &key, &value) == 2) {
        printf("%c:%d\n", key, value);
        continue;
    }

    /* handle a lone "0" sentinel (line containing only the digit 0) */
    if (sscanf(line, " %d", &value) == 1 && value == 0)
        break;

    /* otherwise skip or log malformed lines */
}

Notes and troubleshooting tips:

  • Always check the return value from sscanf/fscanf to avoid printing stale data.
  • fgets keeps parsing to the end of the current line, so stray newlines cannot be misinterpreted as data.
  • Protect the buffer size (avoid tiny arrays) and handle excessively long lines if the input source is untrusted.
  • For simple, perfectly-formed input the loop-condition while (fscanf(fp, " %c%d", &c, &n) == 2) (as suggested by ) is terse and acceptable; for anything that may contain blank/malformed lines, the fgets+sscanf pattern above is safer.

Recommended Answers

All 6 Replies

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 out.

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.

So how can I skip '\n'

Read it.

Member Avatar for Member #838794

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);
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.