SL> Be warned... I am a "newbie" to C. (Please don't hurt me
SL> too much...)
Cool... a user from my own BBS... I'll only hurt you locally. ;->
SL> char *sTemp;
SL> int iTemp;
SL> printf("Enter a number: ");
SL> scanf("%s", sTemp);
Ooo.... so far, so bad. sTemp doesn't point anywhere. You need to give it
some memory.
#define TEMP_LEN 30
char* sTemp = malloc(TEMP_LEN) * sizeof(char)); /* remember to free it
afterwards */
Next problem: scanf. If the user types in more characters than the array has
room for, you'll overwrite it. You could do the following:
scanf("%" STR(TEMP_LEN) "s", sTemp);
Where STR is:
#define _STR(x) #x
#define STR(x) _STR(x)
(A pair of defines are available in Snippets which are close to this [perhaps
a name change] - I should have Snippets available for download, if not, bug
me in private mail and I'll find it for ya.)
Anyway, this is getting ugly. However, there is a reason to this madness,
and it is a point on how to get really ugly code that works. ;-)
Let's try two different solutions at this point.
1. Use scanf.
int main()
{
int iTemp;
int iScanned;
printf("Enter a number: ");
/* Note: you may want to fflush(stdout) if you use non-ANSI functions
* for reading, such as kbhit/getch[e] */
iScanned = scanf("%d",&iTemp);
if (iScanned != 1)
{
/* digits weren't scanned - was non-numeric */
}
else
{
/* digits were scanned, but there could be more after at least one digit.
*/
}
}
This shows the use of scanf's family's return codes. It will return the
number of variables read - in this case, we want 1. Any other number (only 0
is possible) means that fewer than all were read... meaning something
"unexpected" happened. In this case, it would mean that a character not
conforming to the %d specifier was found first.
2. Parse everything manually
This is the form I generaly use because I find it easier to give proper error
messages in complex inputs. i.e., if I'm expecting a single letter followed
by 1 or more digits followed by a dash followed by ... and I miss the dash, I
will be able to tell the user what I was missing a lot easier than using
scanf.
#define INPUT_LEN 30
int main()
{
char input[INPUT_LEN]; /* allocate memory on stack, no need to free */
int value;
char* pCurrentPos = input; /* iterator to walk through the input string */
char* pLastPos = pCurrentPos; /* iterator for last position */
printf("Enter a number: ");
/* see note from #1 - fgets is ANSI */
fgets(input, sizeof(input), stdin);
/* remove the ending \n. */
{
int cr = strlen(input);
if (input[cr] == '\n')
input[cr] = '\0';
}
/* parse the string for digits, etc. */
value = (int)strtol(pLastPos, &pCurrentPos, 10);
/* we think we're done. */
if (pCurrentPos == pLastPos)
{
/* in this case, the last strtol did not find any digits. We
* started with a non-digit. */
}
else if (*pCurrentPos != '\0')
{
/* in this case, we found some digits (because of the else), but
* there are characters following the digits that were not parsed.
* i.e., the user entered "10q" - pCurrentpos would be pointing at
* the q. */
}
else
{
/* everything was parsed completely and correctly. */
printf("You typed %d\n", value);
}
return 0;
}
What a lot of work to do error-correction (error-protection?)! Thus
the reason for so many generic user-entry modules... so we don't have to
continually do all of this... :-)
SL> Is there a way of doing this using a standard function, or
SL> do I have to check for a zero (\0x30?) in sTemp if atoi returns a 0?
You could do this - the only reason for the longer solutions above is to help
you should you want more than just a single number... :-)
---
---------------
* Origin: Tanktalus' Tower BBS (1:250/102)
|