Personal computing discussed

Moderators: SecretSquirrel, just brew it!

• 1
• 2

IntelMole
Grand Gerbil Poohbah
Topic Author
Posts: 3505
Joined: Sat Dec 29, 2001 7:00 pm
Location: The nearest pub
Contact:

### Darned scanf function

Ok this is probably the first post of many

I'm trying to make hex-integer converter, since it's an exercise in this book of mine that I'm learning C from... yeah yeah, learning from a book, get the criticisms out of your systems

Anyways, I've got this far...

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

main()
{
int i, quit, hex, wait;

scanf("%0X", hex);
printf("%x", hex);

wait = sqrt (3.0);
while (wait != 1){
sqrt(wait);
}

}

About the sqrt bit, that's just an ad hoc way of stalling the program so i can see what it's doing, I'm not really concerned about that...

I've not got anywhere with the hex-int conversion, because I don't really understand the scanf function, and I've never been any good at learning it from cryptic definitions from a book or teacher etc.

It either crashes or gives me a GIGO answer...

Only thing is I don't understand why my input is garbage

So I've reduced the project down to a simple input-output program until I get the hang of the scanf function, only I can't...

Anyone wanna show me the light? lol
IntelMole
Living proof of John Gabriel's theorem

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
OK I'll try to help you despite yesterday's disrespectful post of yours .

First: it's not hex-int but hex-dec. Hex. are usually integers, actually.

Q1: You're trying to get a string representing a hex. and convert it manually to an 'int' or to a string representing a dec. ? scanf with the conversion letter 'x' (not 'X' that's only valid for printf and just converts output to uppercase) does it 'automagically'.

About the way of stalling the proggie that was fun but you'd better put a simple scanf there too, anyway.

Q2: What compiler are you using?

Cheers and welcome to the C world.

try this:
``[...]scanf("%0x", &hex);  /* scanf passes a reference */printf("%x", hex);      /* printf passes a value */[...]``
no sig

fc34
Minister of Gerbil Affairs
Posts: 2816
Joined: Wed May 08, 2002 8:39 am
Location: Somewhere
couldnt u jus use an array to store the string?

im new to C too! BTW theres nothing wrong learning from a book!

I remember those days when I taught myself QBASIC without a book, just trial and error here and there!
Windows XP - The 64-bit wannabe with a 32-bit graphics interface for 16-bit extensions to a 8-bit patch on a 4-bit operating system designed to run on a 2-bit processor by a company that can't stand 1-bit of competition

zgirl
Grand Gerbil Poohbah
Posts: 3987
Joined: Tue Jan 01, 2002 7:00 pm
Location: The dark side of the moon
Contact:
Nothing wrong with learning from a book. As long as you have a good book. I learned VB that way.
"I used to think the brain was the most amazing organ in the entire body. Then I realized who was telling me this."
If ignorance were painful, half the posters here would be on morphine drips.

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
BTW I forgot to tell you why your program crashed/threw garbage.

You passed scanf a bogus reference -> it interpreted the (garbage) unitialized value ('hex') of your int as a pointer and stored your input there. This can (and usually does) overwrite some memory used by the OS (this causes unstability/crashes quite often).

If you got lucky & didn't bring the OS to it's knees, the unitialized 'hex' value gets printf-ed with the %x modifier.
no sig

IntelMole
Grand Gerbil Poohbah
Topic Author
Posts: 3505
Joined: Sat Dec 29, 2001 7:00 pm
Location: The nearest pub
Contact:
Disrespectful post???

Yeah, the program either crashed at the scanf stage, or gave an ~8 digit number 20788557 something or other... garbage in other words...

A1:
The stall procedure was there because although I can and have used a scanf to quit the program, that was what was crashing the program, so I figured until I got the scanf function down I'd fall back to a quick bit of nearly-infinite loop, I normally use while(1<2) or somesuch but I couldn't resist using the new-fangled sqrt I'd just found... I dunno if you noticed, but I stuck a declaration in there that i don't use, quit... that was a bit of code leftover from what I didn't delete when i started again...

A2:
I'm using a freebie one I downloaded off the net... Bloodshed Dev-C++, as far as I've pushed it, it's not done too bad, but then again, I haven't really pushed it much, as you can tell

One final question: why the &hex instead of just hex... is that a scanf thing, or is it some hexadecimal-related requirement?

Oh yeah, and "automagically"?

That a programmer's official term? ,
IntelMole

Edit: Huh?

``main(){int quit, hex, wait;printf("Enter hexadecimal number...\n");scanf("%0x", &hex);                         /* scanf passes a reference */printf("%x", hex);                          /* printf passes a value */printf("Press any key to quit");scanf("%d", quit);}``

I'm inputting the following hex a2d3 every time, and that fails, so I'm trying just sticking a in there and seeing what it comes up with... and every time it crashes as soon as I press enter!

Once again for emphasis: huh? Thanks for the help btw,
IntelMole
Living proof of John Gabriel's theorem

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
Disrespectful post???
Yeah that one where you corrected my "theoretic" for "theoretical". Theoretic does appear in my dictionary anyway (= theoretical).

The stall procedure was there because although I can and have used a scanf to quit the program, that was what was crashing the program
I guess you were passing it a value then. Put the '&'. Solved.

I'm using a freebie one I downloaded off the net... Bloodshed Dev-C++, as far as I've pushed it, it's not done too bad, but then again, I haven't really pushed it much, as you can tell
AFAIK it's a good one. Doesn't it support console compiling? that way you shouldn't need to make your program stall.

One final question: why the &hex instead of just hex... is that a scanf thing, or is it some hexadecimal-related requirement?
OK there I go again.

&hex is a reference (the address where 'hex' is). scanf (case sensitive, so no capitals ) needs a reference. If you pass it a value, scanf will think it's a reference anyway (going to somewhere in your memory, as the value indicates, and writing your stuff there. That's hazardous stuff for the OS).

This is 'pointers' stuff. There's a lot of controversy about them. You'll find a lot of scary stuff about this on the net. C/C++ allows you to play with them. This gives you power, but power that will make you goof your programs quite often.

http://info.astrian.net/jargon/terms/a/ ... cally.html

Edit: argg!!! look at your last scanf
BTW 'any key' there should read 'any key as long as it's Enter (Return for Commodorians)
Last edited by muyuubyou on Tue May 13, 2003 1:01 pm, edited 2 times in total.
no sig

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
BTW take that '0' out of scanf. It's doing nothing but maybe crashing your program if your compiler doesn't ignore it as mine does .

scanf("%x", &hex);
no sig

IntelMole
Grand Gerbil Poohbah
Topic Author
Posts: 3505
Joined: Sat Dec 29, 2001 7:00 pm
Location: The nearest pub
Contact:
muyuubyou wrote:
Yeah that one where you corrected my "theoretic" for "theoretical". Theoretic does appear in my dictionary anyway (= theoretical).

Oh yeah, that one... I was still right though, wasn't I?

I guess you were passing it a value then. Put the '&'. Solved.

I meant that I felt that as long as I couldn't get the first scanf right, I shouldn't bother putting another set of problems in there, and stick with what I know works ...

AFAIK it's a good one. Doesn't it support console compiling? that way you shouldn't need to make your program stall.

Good question, not yet found that option though...

&hex is a reference (the address where 'hex' is). scanf (case sensitive, so no capitals ) needs a reference...

Thanks, very well explained

This is 'pointers' stuff. There's a lot of controversy about them. You'll find a lot of scary stuff about this on the net. C/C++ allows you to play with them. This gives you power, but power that will make you goof your programs quite often.

No sh*t

http://info.astrian.net/jargon/terms/a/automagically.html
I stand corrected... I believe that makes it 1-1 ...

Edit: argg!!! look at your last scanf

Uh huh, <does "poor boy looking for help" look...>

Stuck an amperand on the quit variable, but I still think the problem is with the first scanf since it crashes straight after that...

Of course I could be utterly wrong
IntelMole
Living proof of John Gabriel's theorem

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
OK copy paste this:

intelMole.c
``#include <stdio.h>int main(void) { int hex, wait, quit;printf("Enter hexadecimal number...\n"); scanf("%x", &hex);                        /* scanf passes a reference*/ printf("%d", hex);                          /* printf passes a value */ printf("\nEnter a small beautiful number to quit"); scanf("%d", &quit); return 0; /* Tell the OS there was no problem */} ``

printf("%d", hex); /* printf passes a value */
...so the output is decimal (a bit more interesting )
no sig

IntelMole
Grand Gerbil Poohbah
Topic Author
Posts: 3505
Joined: Sat Dec 29, 2001 7:00 pm
Location: The nearest pub
Contact:
ROFLMAO

I've just done a copy and paste of your code, which was virtually identical to my version (I added the & in the last scanf...), I've run it... stuck in "a" as the value...

STIL it crashes!

<homer> Something's wrong... </homer>

Even though I KNOW your code is right (okay, maybe I've a strong inkling), it still crashes the instant after the value is entered...

V confusing...

Ok this is probably the first post of many

Warned ya ,
IntelMole[/quote]

edit: found problem... I was running the .c file instead of the .dev file... which seems to have found the problem...

IntelMole
Living proof of John Gabriel's theorem

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
Good thing you show some confidence

IntelMolev2_0.c
``#include <stdio.h>int main(void) { int hex, quit;printf("Enter hexadecimal number...\n"); scanf("%x", &hex);                      /* scanf passes a reference*/ printf("%x hex is %d dec", hex, hex);        /* printf passes a value */ printf("\nEnter a small beautiful number to quit: "); scanf("%d", &quit); printf("Have a nice day\n");return 0; /* Tell the OS there was no problem */} ``

If this doesn't work send it to the guys at BloodShed. Maybe they have some lack of %x support (nobody uses that **** with scanf ).

Works here. Just tried it using gcc with -pedantic flag.

See you 2morrow
no sig

liquidsquid
Minister of Gerbil Affairs
Posts: 2559
Joined: Wed May 29, 2002 10:49 am
Location: New York
Contact:
My compiler help says you have to use an unsigned int as the pointer to pass, though I doubt that is casing the problem since they are typically the same size.

void main(void)
{
int quit;
unsigned int hexVal;

scanf("%08X", &hexVal); /* scanf passes a reference, 8 numbers max, x == X*/
printf("0x%08X hex is %d dec", hexVal, hexVal); /* printf passes a value capitol X makes hex characters upper case */

printf("\nEnter a small beautiful number to quit: ");
scanf("%d", &quit);
printf("Have a nice day\n");

return 0; /* Tell the OS there was no problem */
}

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
Well liquidSquid, I checked the ANSI and says nothing about the need of using unsigned there. Thanks anyway for taking the time to check it and not leaving all the work to me .

BTW main can't return void (that's not standard), more even so if you explicitly return 0 at the end of the proggie.

scanf does not support capital 'X' (it's 'x' but compilers usually swallow that anyway). Printf does do what you say if you use capital X (in case you want uppercases...).

stdio.h is needed.

I think I'll download his compiler (he said he used Bloodshed) to check it out... I think that compiler is french, so it surrenders quite easily
no sig

liquidsquid
Minister of Gerbil Affairs
Posts: 2559
Joined: Wed May 29, 2002 10:49 am
Location: New York
Contact:
It can't return void only on programs that are within other calling programs like an OS on a PC. I have been programming embedded stuff, so if you even exit main() you are lost in space. My main() is the primary end all of be all function, and has no return (where would you go?). Sorry about any confusion.

BTW I tried this routine on my system (68EZ328 based) and it seems to work and compile just fine, but it took some doing since I didn't have the I/O hooked up to allow scanf and printf to work properly. I have my own much more simple routines for these functions to reduce the footprint.

If all else fails, have the user input a string instead, limiting the characters to 0-9, A-F, then convert the string to an int manually. Then printf should be able to format it any way you want. What you may be running into is the compiler isn't completly supportive of all input types in the scanf function. Many free compilers are not 100% complient, or will do things slightly different than the ANSI standard. You will have to pour through the documentation to see if the scanf() has hex input support implimented.

-LS

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
Well I have plenty of compilers. I usually go fine with GCC.

IntelMole is who's using Bloodshed and is trying to get into the wild C world

Yeah LS printf and scanf aren't exactly the bed for embedded systems. Worked in Japan programming microcontrollers and I know for sure

Hey IntelMole, what version did you download? are you using the IDE?
Looks like it's using GCC (same as me!). Open a DOS shell and try compiling it using the command line (gcc -c crap.c -o crap.exe)
no sig

fc34
Minister of Gerbil Affairs
Posts: 2816
Joined: Wed May 08, 2002 8:39 am
Location: Somewhere
I just use LCC BASE system for windows. Works fine, and is free.

Windows XP - The 64-bit wannabe with a 32-bit graphics interface for 16-bit extensions to a 8-bit patch on a 4-bit operating system designed to run on a 2-bit processor by a company that can't stand 1-bit of competition

IntelMole
Grand Gerbil Poohbah
Topic Author
Posts: 3505
Joined: Sat Dec 29, 2001 7:00 pm
Location: The nearest pub
Contact:

IDE version?

lol, I dunno, I just run the thing,
IntelMole
Living proof of John Gabriel's theorem

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
Bloodshed Dev-C++ 4.0 is a full-featured programming environment and compiler for creating software in C++. Included in the Dev-C++ environment are all of the standard features necessary for writing, compiling, debugging, and executing programs written in C.
Strictly for the hard-core C++ programmer, Dev-C++ allows you to compose all of your source code without many of the hand-holding features and expenses included in many of the available programming environments.

If you know how to program in C++, Bloodshed Dev-C++ 4.0 lets you do exactly that.

So it's 4.0. I won't care about the "strictly for the hardcore C++ programmer". C++ won't be any more difficult for such claims .

I guess you're using the IDE (Integrated Development Environment).

Try opening a DOS shell and doing "gcc" and see what happens...

I'm using Yahoo messenger, just in case you didn't notice. I have a MSNmessenger account too but I don't use it too often. Maybe that's better way to get this running (when I have the time, of course ).

I guess you want to start programming stupid games real soon, don't you?. I prefer linux rather than windows as target anyway but we can try making things portable.
no sig

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain

Just double-clicked on the .c (associated .c to it during set-up, as it does by default) and compiled-executed it...

You tell me what you're doing, mate
no sig

IntelMole
Grand Gerbil Poohbah
Topic Author
Posts: 3505
Joined: Sat Dec 29, 2001 7:00 pm
Location: The nearest pub
Contact:
Muyuubyou, I've got the thing working... yello?

I was compiling the .c file, which I expect caused the compiler to screw itself and produce silly code somehow. Compiling the .dev file produced a program that works flawlessly...

BTW, I have a theory about how the thing works...

When you input the hex number, as long as C knows it's a hex number, it'll store the number in memory, but in binary. From there, binary -> integer conversion is easy. Am I close?

Thanks again,
IntelMole
Living proof of John Gabriel's theorem

muyuubyou
Grand Gerbil Poohbah
Posts: 3222
Joined: Wed Aug 28, 2002 6:19 am
Location: London, UK or Tokyo/Yokohama, Japan or Madrid, Spain
Of course it's stored in binary . The scanf function does all the conversion (in the same way it does when you pass it a dec number via %d).

In fact, when you explained your problem I thought you wanted to program the conversion yourself, and not simply calling scanf to do it

How is your progress going? I want you to start with some SDL and OpenGL real soon.
no sig

Veritas
Gerbil First Class
Posts: 113
Joined: Wed Dec 26, 2001 7:00 pm
Location: Houston, TX
Contact:
The problem might just be that Dev-C++ is a C++ compiler, not a C compiler. While C is virtually a subset of C++, there are some C things that just will not work with an ANSI C++ compiler.

LiquidSquid:
``scanf("%08X", &hexVal); /* scanf passes a reference, 8 numbers max, x == X*/ ``

C does not have references. Just pointers.
``&hexVal``
is a pointer to hexVal, not a reference. The scanf function only takes pointers to variables, not references (because they don't exist in C). It is very important to understand the difference if you get into C++ or any other language that has real references.

muyuubyou:
How is your progress going? I want you to start with some SDL and OpenGL real soon.

Cool, I am writing a windows app that uses OpenGL at work right now to do some graphical analyzation of data we collect from the international space station. Let me know if you need any help.
Last edited by Veritas on Mon May 19, 2003 1:33 pm, edited 1 time in total.

Veritas
Gerbil First Class
Posts: 113
Joined: Wed Dec 26, 2001 7:00 pm
Location: Houston, TX
Contact:
``void main(void) ``

Ack!!!!

Never use main like that. Even if your compiler allows it. It is not valid ANSI C and will not compile with compilers that actually do make the effort to be standard compatible. And if the OS you are running the program on expects a value to be returned, returning a void could be all kinds of trouble.

main() should always return an int as such:

``int main(void){   return 0;}``

EDIT: Yes, I am a stickler for following standards.

Craig P.
Posts: 285
Joined: Tue Dec 31, 2002 3:12 am
Location: South Bend, IN
liquidsquid wrote:
void main(void)

Non-standard, diagnostic required. Microsoft violates the standard by accepting this without a diagnostic.

I don't know if the C standard allows it, but the C++ standard allows no return from main(), e.g.

``int main(void){// ... etc ... - no return statement}``

Of course, VC6 (haven't tried VC7.1 yet) converts this into void main().

just brew it!
Gold subscriber
Posts: 50029
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer
I'm a little late to this party, it seems...

For interactive command line programs, fgets() is actually a bit better than scanf(), as it is line-oriented rather than field-oriented. E.g., you can re-prompt the user if they don't enter a valid hex number, and you can also allow the user to just hit Enter to exit, instead of having to enter another number:

``#include <stdio.h>#include <ctype.h>#include <stdlib.h>int main(void){    char buffer[12];    long value;    do    {        printf("Enter hexadecimal number...\n");        fgets(buffer, sizeof(buffer), stdin);   /* read string */    } while (!isxdigit(buffer[0]));             /* until we get valid hex */    value = strtol(buffer, NULL, 16);           /* convert from hex */    printf("0x%08lX hex is %ld dec\n", value, value);     /* output */    printf("Hit Enter to quit: ");    fgets(buffer, sizeof(buffer), stdin);       /* wait for user to hit Enter */    printf("Have a nice day\n");    return 0; /* Tell the OS there was no problem */}``
Last edited by just brew it! on Mon May 19, 2003 2:46 pm, edited 1 time in total.

Veritas
Gerbil First Class
Posts: 113
Joined: Wed Dec 26, 2001 7:00 pm
Location: Houston, TX
Contact:
I don't know if the C standard allows it, but the C++ standard allows no return from main(), e.g.

I tried it with gcc and it creates an executable, but it gave me this warning:

main.c:10: warning: control reaches end of non-void function

just brew it!
Gold subscriber
Posts: 50029
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer
Veritas, what version of gcc and what command line switches? With gcc 3.2 and -pedantic (or -Wall) I don't get the warning. It seems that main() is treated as a special case; for any function other than main(), -Wall will result in a warning if a non-void function is missing the final return statement.

Veritas
Gerbil First Class
Posts: 113
Joined: Wed Dec 26, 2001 7:00 pm
Location: Houston, TX
Contact:
I used -pedantic and -Wall

However, I was actually using mingw (gcc v3.2 for windows) so that may make a difference.

Edit:
I just tried it on my BSD box running gcc 2.95.3 and got this
[job ~/test]\$ gcc -Wall main.c -o main
main.c: In function `main':
main.c:6: warning: control reaches end of non-void function
[job ~/test]\$
Last edited by Veritas on Mon May 19, 2003 3:56 pm, edited 1 time in total.

just brew it!
Gold subscriber