problem on fscanf()

I have declared a variable “data” with type “unsigned short”, and I wrote it to a file use fprintf. I tried to read the data out using fscanf in another method, but the number did not come out right.

Could anyone tell me what the correct data type I should use when I do
fscanf("%?", &data)? (I tried to use %u and %d, but none of them give the right number. I’ve also checked the file, and the number in the file seems correct. )

Thanks a lot!

fscanf(file, “%u”, &data ) works for me. Post your code for both reading and writing.

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

double inc = 0.03142;

int main( void )
{
FILE *fp;
double sinval, reads;
unsigned short insinval, inreads;

/*open the file to right*/
fp = fopen( "myfile.dat", "w" );

if( fp != NULL ) {

  for( i = 0; i<201; i++)
  {
     sinval = sin(x); 
     insinval = sinval*10000;
     fprintf(fp, "%u", insinval); 
     x = x + inc; 
   }

   fclose(fp); 

 }

 else 
    printf("fail to open file"); 

 /*open the file to read*/
 if((fp = fopen("myfile.dat", "r")) != NULL)
 {
    for(i = 0; i<201; i++){
     
       fscanf(fp, "%u", &inreads); 
       printf("%u \t", inreads ); 
    }
 }
 if(fclose(fp)==EOF)
printf("fail") ; 

}

Thanks for helping me.

If you take a look inside of myfile.dat you will find that there is no white spaces, it’ll be one long jumble of digits.

Try, fprintf(fp, “%u\n”, insinval);

yeah, what evan said. ;)

This is probably going to go under the pedantic column, but unsigned shorts are to be formatted by %hu, signed shorts by %hd, with unsigned char being %hhu.

The reason why using the format %d for short and char works is the compiler will generally keep variables word (32bit) aligned on the stack, with the other part of the data zero’d off. This of course depends on the optmization. If you where to optmize for memory, your code may stop working. If you are using packed data, then you will of course be displaying 2 shorts put together (and that just sounds bad doesn’t it :slight_smile: )

If you add -w9, gcc will warn you about impropper format strings.

Oh well.

cheers,
Tom

Thanks all of you, now it works for me. Right now, after I wrote the number in each line, it seems alright.

Any way, again thank you very much! :smiley:

Funny I always though it works because of automatic promotion to int type.

I just tested with compiling in 16 bit and 32 mode (QNX4) and in each case the char was promoted to int ???

For printf looks so, scanf no. But why count on the automagic cast??

#include <stdio.h>

int main( void )
{
        short lump[ 4 ];

        for( int ctr = 3; ctr >= 0; ctr-- )
        {
                printf( "data %d: ", ctr );
                scanf( "%d", &lump[ ctr ] );
        }

        for( int ctr = 0; ctr < 4; ++ctr )
                printf( "%hd\n", lump[ ctr ] );

        for( int ctr = 3; ctr >= 0; ctr-- )
        {
                printf( "data %d: ", ctr );
                scanf( "%hd", &lump[ ctr ] );
        }

        for( int ctr = 0; ctr < 4; ++ctr )
                printf( "%hd\n", lump[ ctr ] );

        return 0;
}

When run begets

[thomas@loman test]$ cc -o fmt -Wall fmt.cc
fmt.cc: In function `int main()':
fmt.cc:10: warning: int format, different type arg (arg 2)
[thomas@loman test]$ ./fmt
data 3: 8
data 2: 7
data 1: 6
data 0: 5
5
0
0
0
data 3: 8
data 2: 7
data 1: 6
data 0: 5
5
6
7
8

Notice how the most short of the int over wrote the next element in the array, but when you give scanf the apropriate format the array contains what you would expect.

It is scary to go through code that works despite the best efforts of the author. BTW, yeah, the example was done on my Linux box, my nto box has temporarily donated it power supply to another box, but I would suspect QNX did not make that many mods to gcc???