0

Problem:

I wrote a C program that is supposed to loop through an input file and display its tabular contents in an identically laid out table, except, unlike the input file, the values outputted should be in nice evenly tabbed columns.

The text file I'm reading has the following contents:

name surname 123 4.2 f
sara dddd 222 3.2 f
dan ssss 1233 1.3 m
ann aaaa 443 2.2 f

But the output is wrong:

output

Notice the unwanted line-wrapping, where the value that should be displayed in the last column becomes the first column of the next line.

The program:

    int i, j;
    char c;
    double d;
    char str[10];
    char t[6]="ssidc"; //Encoded column types descriptor (e.g. string, string, int, double, char"

    while(!feof(fa)) {

    for(i = 0; i < 5; i++) {
        switch(t[i]) {
            case('s'): 
                fscanf(fa,"%s",str);
                printf("%s\t",str);
                break;
            case('c'):
                fscanf(fa,"%c",&c);
                printf("%c\t",c);
                break;
            case('d'):
                fscanf(fa,"%lf",&d);
                printf("%.1lf\t",d);
                break;
            case('i'):
                fscanf(fa,"%d",&j);
                printf("%d\t",j);
                break;
            default:
                break;
        }
    }
    printf("\n");//new line
}
clearlight
  • 12,255
  • 11
  • 57
  • 75
R. Arda
  • 53
  • 1
  • 6
  • 4
    Please see [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/q/5431941/2173917) – Sourav Ghosh Jan 01 '17 at 12:15
  • 1
    Did you run the code inside a debugger to trace through the program line by line inspecting the values of the relevant variables to learn what is really going on? – alk Jan 01 '17 at 12:18
  • Try using the format " %c" for the 'c' case. – Marc Balmer Jan 01 '17 at 12:22
  • 1
    If you are delimiting using spaces, consider to skip all of the spaces explicitly, (e.g. using [`fgetc(3)`](http://man.openbsd.org/POSIX-2013/cat3/fgetc.0) at the end of the `for`) or try using [`fgets(3)`](http://man.openbsd.org/POSIX-2013/cat3/fgets.0) and [`strtok(3)`](http://man.openbsd.org/POSIX-2013/cat3/strtok.0). The latter method has less file operations and is therefore faster. You also have a single address range where all of your string is stored for arbitrary operations (e.g. parsing) making the code more intuitive/obvious (at least for some people). – benaryorg Jan 01 '17 at 13:03

1 Answers1

1

scanf("%c" reads any char, but at the time you call it the current position is on a space (you've just parsed a float), it is then read as a char. You need to skip it by providing an extended format processing directive:

fscanf(fa,"%*[ ]%c",&c);

Read scanf manual to understand how it works.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69