1
votes

How can one use scanf to scan in an integer amount of characters and simply stuff them into an unsigned int without conversion?

Take an example, I have the following input characters (I have put them in hex for visibility):

5A 5F 03 00 FF FF 3D 2A

I want the first 4 (because 4 char's fit in an int). In base 10 (decimal) this is equal to 221018 (big-endian). Great! That's what I want in my int. This seems to work as expected:

scanf("%s", &my_integer);

Somehow it seems to get the endianness right, placing the first character in the LSB of the int (why?). As you would expect however this produces a compiler warning as the pointer must be to a character array (man 3 scanf).

An alternate approach without using scanf():

for (int i = 0; i < 4; i++)
{
    my_integer |= (getchar() << i * 8);
}

Note that I don't intend to do any conversion here, I simple wish to use the pointer type to specify how many characters to read. The same is true if &my_integer was a long, I would read and store eight characters.

Simple really.

It appears my idea behind the use of scanf isn't correct and there must be a better approach. How would you do it?

N.B. I'm aware type sizes are architecture dependent.

1
scanf and printf work on text; they read (and convert) and write text. You want to work on raw, binary data. The functions fread and fwrite are designed for such I/O of raw data. - M Oehm
"Simple really." -- No, not at all. :) - unwind
@M Oehm Agree in general about scanf() and text other than that scanf("%c" ...)` will nicely read any binary data into a char as long as the stream stdin is in binary mode. - chux - Reinstate Monica
Ah! Wrong tool for the wrong job. This may be of use: en.wikipedia.org/wiki/C_file_input/output - Emphacy

1 Answers

2
votes

So you want to read 4 bytes from stdin and use them as they are as the representation of a 32-bit big-endian value:

int my_integer;

if (fread (&my_integer, sizeof my_integer, 1, stdin) != 1) {
    /* Some problem... */
}