newbie question, fread problem

B

bob

I can't get 'number' to print like I think it should:


int main()
{
int number;
printf("two digit number please:\n");
fread(&number, sizeof(int), 1, stdin);
printf("your number is: %d\n", number);
return 0;
}

the last printf gives me the address (I think so, anyway) of 'number'.
Also after the first printf I get a newline as expected, ..i enter say
45..hit enter...and another newline pops up.....why? Then finally the
last print f prints teh address as i mentioned.

if I replace int with char then things work like I would expect.

Thanks
 
K

Keith Thompson

bob said:
I can't get 'number' to print like I think it should:


int main()
{
int number;
printf("two digit number please:\n");
fread(&number, sizeof(int), 1, stdin);
printf("your number is: %d\n", number);
return 0;
}

the last printf gives me the address (I think so, anyway) of 'number'.
Also after the first printf I get a newline as expected, ..i enter say
45..hit enter...and another newline pops up.....why? Then finally the
last print f prints teh address as i mentioned.

The code you posted is missing a required "#include <stdio.h>" -- but
if your actual code didn't have that, it wouldn't compile (the
compiler wouldn't recognize the identifier "stdin"). Always post the
*exact* code that you fed to the compiler.

The last printf prints the value of "number", not its address.
That value happens to be garbage.

fread() reads binary data, not text. If you enter the character
string "45", fread() won't convert it to the integer value 45; it will
interpret the input characters as bytes composing an int value.

When I tried this program myself, I entered "45" followed by a
newline, then I had to enter another newline to make a total of 4
input characters (sizeof(int) is 4 on my system). The value stored in
"number" was 168441140, the result of storing the integer values of
'4', '5', '\n', and '\n' into a 4-byte integer. Your results might
differ, but see if you can figure out why you got the result you did.

Use scanf() to read an integer -- or, better yet, use fgets() to read
a line of input, then use sscanf() to parse it.
 
W

Walter Roberson

I can't get 'number' to print like I think it should:
int main()
{
int number;
printf("two digit number please:\n");
fread(&number, sizeof(int), 1, stdin);
printf("your number is: %d\n", number);
return 0;
}
the last printf gives me the address (I think so, anyway) of 'number'.
Also after the first printf I get a newline as expected, ..i enter say
45..hit enter...and another newline pops up.....why? Then finally the
last print f prints teh address as i mentioned.

if I replace int with char then things work like I would expect.

Thanks

fread() interprets the input stream in binary.

Since it is not just sitting waiting for input, I am going to guess
that you are running on a PC, and that the input stream you get when
you type in 45 and press newline is '4' '5' carriage-return linefeed.
These bytes would be pasted together in an order that is
dependant on the processor's representation of integers...
maybe '5' then '4' then linefeed then carriage-return .
If you happen to be using ASCII as the character set,
'5' is hex 0x35, '4' is hex 0x34, carriage-return is 0x0d
and linefeed is 0x0a. Pasted together, 0x35340d0a .
The decimal equivilent of that would be 892603658 .

If you take whatever value you got and convert it to hex
and then look byte by byte at the data, you will probably find
a similar pattern.

If you want to type in the characters 4 then 5 and have that
interpreted as the decimal number fourty-five, then you need
to use one of the methods of converting characters to numbers.
There are several different methods of doing that; I suggest
that you examine strtol().
 
Z

Zara

I can't get 'number' to print like I think it should:


int main()
{
int number;
printf("two digit number please:\n");
fread(&number, sizeof(int), 1, stdin);
printf("your number is: %d\n", number);
return 0;
}

the last printf gives me the address (I think so, anyway) of 'number'.
Also after the first printf I get a newline as expected, ..i enter say
45..hit enter...and another newline pops up.....why? Then finally the
last print f prints teh address as i mentioned.

if I replace int with char then things work like I would expect.

Thanks

fread is un unformatted input function. It will wait for you to press
at least sizeof(int) keys before returning, and will stoire raw key
values in the space allocated to number. For instance, if you press
'4', '5', '6' and 'return', you might get (in an Intel 32 bit
architecture), number with a value of 0x0d63534 (ascii codes of keys,
in lastto first order).

What you want is a formatted input function, l¡ke scanf:
scanf("%d",&number);
That will give you the results you expect.

Remember:

FORMATTED: printf/scanf
UNFORMATTED: fwrite/fread

Best regards,
Zara
 
K

Keith Thompson

I can't get 'number' to print like I think it should:
int main()
{
int number;
printf("two digit number please:\n");
fread(&number, sizeof(int), 1, stdin);
printf("your number is: %d\n", number);
return 0;
}
the last printf gives me the address (I think so, anyway) of 'number'.
Also after the first printf I get a newline as expected, ..i enter say
45..hit enter...and another newline pops up.....why? Then finally the
last print f prints teh address as i mentioned.
[snip]

fread() interprets the input stream in binary.

Since it is not just sitting waiting for input, I am going to guess
that you are running on a PC, and that the input stream you get when
you type in 45 and press newline is '4' '5' carriage-return linefeed.
These bytes would be pasted together in an order that is
dependant on the processor's representation of integers...
maybe '5' then '4' then linefeed then carriage-return .

That's not likely. The fread() reads from stdin, which is opened in
text mode, so an end-of-line would appear as a single '\n' character.
The OP says that "another newline pops up"; I suspect he meant that
the program waits for another newline, resulting in "45\n\n" being
interpreted as a 4-byte int.
 
A

al3x4nder

hi, all!
i think, better way is using gets() instead fread()
in this context(i.e. question), for output should be used
puts();

or i`m wrong?
 
A

al3x4nder

p.s. or also can be used getchar():
int ch;
char * buff[1024], * ptr = buff;

while((ch = getchar()) != 10){
*(ptr++) = ch;
}
printf("%s\n", buff);
 
C

Chris Dollin

hi, all!
i think, better way is using gets() instead fread()
in this context(i.e. question), for output should be used
puts();

or i`m wrong?

You missed out the `f` from `fgets`.
 
C

Chris Dollin

p.s. or also can be used getchar():
int ch;
char * buff[1024], * ptr = buff;

Urm -- did you try compiling this? [Clearly not, because the
code isn't inside a function ...]

You've declared `buff` as an array of pointer-to-char (which seems
implausible), `ptr` as `pointer-to-char` (fine) and then initialised
`ptr` to `&buff[0]` (wrong).
while((ch = getchar()) != 10){
*(ptr++) = ch;
}
printf("%s\n", buff);

I don't see the code for adding the final 0.
 
?

=?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=

p.s. or also can be used getchar():
int ch;
Thisone is ok.
char * buff[1024], * ptr = buff;
You want an array of chars. Not an array of char pointers.
while((ch = getchar()) != 10){
You should the magic 10 there. Use e.g '\n'
*(ptr++) = ch;
You must check that you don't overflow the array you read into.
}
printf("%s\n", buff);
You must make sure the array really holds a string, else
the above printf might blow up. nul terminate the array.
 
A

al3x4nder

yes, i`m compile this code, and it works OK!
it`s full version:
int main(int argc, char * argv[]){
int ch;
char * buff[1024], * ptr = buff;

while((ch = getchar()) != 10){
*(ptr++) = ch;
}
printf("%s\n", buff);
return 0;
}
 
R

Robert Harris

yes, i`m compile this code, and it works OK!
it`s full version:
int main(int argc, char * argv[]){
int ch;
char * buff[1024], * ptr = buff;

while((ch = getchar()) != 10){
*(ptr++) = ch;
}
printf("%s\n", buff);
return 0;
}

It may work most of the time. What happens if:

1. There does not happen to be a NUL byte in the buffer following the
characters entered
2. There is no line feed in stdin
3. There are more than 1023 characters before the line feed

And don't compiler warnings worry you?

Robert
 
C

Chris Dollin

no, i meant gets(), get string from stdin

I really really hope you didn't mean `gets`, since it's an
open invitation to failure and subversion of your code.

"This is ... wrong tool. Never use this." (Zathras)
 
C

Chris Dollin

yes, i`m compile this code, and it works OK!
it`s full version:
int main(int argc, char * argv[]){
int ch;
char * buff[1024], * ptr = buff;

If your compiler didn't report a problem at this point,
get a better compiler - the types don't match.
while((ch = getchar()) != 10){

And at this point (there's no declaration for `getchar`).
*(ptr++) = ch;
}
printf("%s\n", buff);

And at this point (there's no declaration for `printf`).
 
A

al3x4nder

ok, ok...
just replace ``while'' loop to ``for'' whith counter and
it resolve overflow trouble :)
 
A

al3x4nder

ok, i promise be carefuly in future :)
at last present for comunity last, more security solution:

#include <stdio.h>

int main(int argc, char * argv[]){
int ch, cnt;
char buff[1024], * ptr = buff;

for(cnt = 0;(ch = getchar()) != 10 && cnt < 1024; cnt++){
*(ptr++) = ch;
}
* ptr = '\0';
printf("%s\n", buff);
return 0;
}
 
S

stathis gotsis

yes, i`m compile this code, and it works OK!
it`s full version:
int main(int argc, char * argv[]){
int ch;
char * buff[1024], * ptr = buff;

while((ch = getchar()) != 10){
*(ptr++) = ch;
}
printf("%s\n", buff);
return 0;
}

How about this one:

#include <stdio.h>

int main(void)
{
int ch;
unsigned int count=0;
char buf[1024],*ptr=buf;

while ((ch=getchar())!='\n')
{
if (++count>=sizeof(buf))
break;
*ptr++=ch;
}

*ptr='\0';

printf("%s\n",buf);

return 0;
}
 
S

stathis gotsis

ok, i promise be carefuly in future :)
at last present for comunity last, more security solution:

#include <stdio.h>

int main(int argc, char * argv[]){
int ch, cnt;
char buff[1024], * ptr = buff;

for(cnt = 0;(ch = getchar()) != 10 && cnt < 1024; cnt++){
*(ptr++) = ch;
}
* ptr = '\0';
printf("%s\n", buff);
return 0;
}

That can read up to 1024 characters, while it should read up to 1023 to save
the last byte for '\0'.
 
C

CBFalconer

yes, i`m compile this code, and it works OK!
it`s full version:
int main(int argc, char * argv[]){
int ch;
char * buff[1024], * ptr = buff;

while((ch = getchar()) != 10){
*(ptr++) = ch;
}
printf("%s\n", buff);
return 0;
}

Now try entering a CTRL-Z (or CTRL-D, depending on OS) alone,
followed by <enter> and see what nasty things happen. Also look up
the meaning of \n in the C language. But you are almost there!
Another thing to watch out for is buffer overrun. There are other
errors, but you show promise.

Before replying or posting again, please read the URLs referenced
in my sig. below. Usenet articles should always include context,
because the reader usually does not have convenient access, and in
fact may never have received, any previous articles. This is
totally contrary to the *apparent* view given by the broken google
interface. Make each article stand by itself.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top