atoi query

P

ptq2238

Hi,

I have written this code to help me learn C but I'm not sure why gcc -
Wall is giving me an error when I compile

Basically I want to read in a character then a number and then
manipulate the number.
I've tried scanf such as scanf("%c%d",&letter,&number); but when I
type in say 2 letters instead of 1 letter and 1 number, I get a zero
for the 2nd value as it doesn't match what scanf is expecting so I'm
trying fgets.

#include <stdio.h>
#define LINESIZE 4

int main()
{
char line[LINESIZE];
int temp,temp2;

printf("Please enter a letter and a value: ");
fgets(line, LINESIZE, stdin);

printf("This line was entered: %s\n",line);

printf("line[0] is %c\n ",line[0]);
printf("line[1] is %c\n ",line[1]);
temp = atoi(line[1]);

printf("temp is %d\n ",temp);
temp2 = temp + 5;
printf("temp2 is %d\n ",temp2);

return 0;
}

Then on compile,
gcc -Wall getloc_val.c
getloc_val.c: In function `main':
getloc_val.c:17: warning: implicit declaration of function `atoi'

The book I'm refering to mentions that I can do this but why am I
getting the implicit warning ?
Pat
 
R

Richard Bos

I've tried scanf such as scanf("%c%d",&letter,&number); but when I
type in say 2 letters instead of 1 letter and 1 number, I get a zero
for the 2nd value as it doesn't match what scanf is expecting so I'm
trying fgets.

Yup, that's correct, and that's the right solution.
#include <stdio.h>
#define LINESIZE 4

(This is a rather low value, though. Do you really expect to get A24
_all_ the time? You probably want to handle ABC23, A 24, and A7632 with
a slightly more useful error message than "input not understood", and
you don't want your program to accept the latter as A76.)
int main()
{
char line[LINESIZE];
int temp,temp2;

printf("Please enter a letter and a value: ");
fgets(line, LINESIZE, stdin);

printf("This line was entered: %s\n",line);

printf("line[0] is %c\n ",line[0]);
printf("line[1] is %c\n ",line[1]);
temp = atoi(line[1]);

printf("temp is %d\n ",temp);
temp2 = temp + 5;
printf("temp2 is %d\n ",temp2);

return 0;
}

Then on compile,
gcc -Wall getloc_val.c
getloc_val.c: In function `main':
getloc_val.c:17: warning: implicit declaration of function `atoi'

This, however, is not the right solution.
The book I'm refering to mentions that I can do this

Then either the book is wrong (or at best incomplete), or you missed a
bit.
but why am I getting the implicit warning ?

Because you didn't declare atoi(). Just as you have to #include
<stdio.h> for printf(), and <string.h> for strcpy(), you also have to
#include <stdlib.h> for atoi().
But you don't want to use atoi(), anyway. It has a few problems, because
its error handling is not so much bad as non-existent. Use strtol()
instead; you'll find it declared in <stdlib.h> as well.

Richard
 
F

Flash Gordon

Hi,

I have written this code to help me learn C but I'm not sure why gcc -
Wall is giving me an error when I compile

You should be using "-ansi -pedantic -Wall -O -W" or for incomplete C99
support "-std=c99" instead of -ansi. This will generate warnings for a
lot more questionable practices.
Basically I want to read in a character then a number and then
manipulate the number.
I've tried scanf such as scanf("%c%d",&letter,&number); but when I
type in say 2 letters instead of 1 letter and 1 number, I get a zero
for the 2nd value as it doesn't match what scanf is expecting

It's worse than that. It won't have written anything to number, that it
contained 0 was merely luck. The return value of scanf will have told
you it only did one conversion.
> so I'm
trying fgets.

This is a much better solution.
#include <stdio.h>
#define LINESIZE 4

That's a very short line limit!
int main()
{
char line[LINESIZE];
int temp,temp2;

printf("Please enter a letter and a value: ");

You should flush stdout otherwise the above prompt might not be
displayed before waiting for input.
fgets(line, LINESIZE, stdin);

printf("This line was entered: %s\n",line);

printf("line[0] is %c\n ",line[0]);
printf("line[1] is %c\n ",line[1]);

I think you will find that you need to identify the start of the number
(isdigit will help, but remember to allow for signs) before trying to
convert it.
temp = atoi(line[1]);

printf("temp is %d\n ",temp);
temp2 = temp + 5;
printf("temp2 is %d\n ",temp2);

return 0;
}

Then on compile,
gcc -Wall getloc_val.c
getloc_val.c: In function `main':
getloc_val.c:17: warning: implicit declaration of function `atoi'

The book I'm refering to mentions that I can do this but why am I
getting the implicit warning ?

atoi is declared in stdlib.h, if your book did not tell you this then it
is probably time to get a new book. Also, it is generally better to use
strtol so that you have a chance to do error checking.
 
R

Richard Heathfield

(e-mail address removed) said:
char line[LINESIZE];
temp = atoi(line[1]);

Others have noted that you should be using a longer buffer and that
strtol would serve your needs better than atoi, but nobody appears to
have noticed the problem with your argument to atoi.

atoi (and, when you bite the bullet and choose to use it instead,
strtol) must be supplied with a string, not a character, for converting
to an integer. line[1] is not a string, but a single char. A string is
a sequence of characters terminated by the first null character. If you
want to tell, say, atoi to start at the second character of your
string, you can do this by passing the address of that second character
of the string, like this:

temp = atoi(&line[1]);

Incidentally, to convert a single character to a digit is easy. Provided
it /is/ a digit, you can simply subtract '0' from it, because '0', '1',
'2', '3', ... '8', '9' (unlike the alphabet, alas) are guaranteed to
have contiguous and ascending coding points. In other words, the digit
characters are in a little block all of their own, and subtracting '0'
from any value in that block will give you the "distance" from '0'.
Thus, '4' - '0' gives you 4, '7' - '0' gives you 7, etc.
 
D

Default User

Hi,

I have written this code to help me learn C but I'm not sure why gcc -
Wall is giving me an error when I compile

Basically I want to read in a character then a number and then
manipulate the number.
I've tried scanf such as scanf("%c%d",&letter,&number); but when I
type in say 2 letters instead of 1 letter and 1 number, I get a zero
for the 2nd value as it doesn't match what scanf is expecting so I'm
trying fgets.

#include <stdio.h>
#define LINESIZE 4

int main()
{
char line[LINESIZE];
int temp,temp2;

printf("Please enter a letter and a value: ");
fgets(line, LINESIZE, stdin);

printf("This line was entered: %s\n",line);

printf("line[0] is %c\n ",line[0]);
printf("line[1] is %c\n ",line[1]);
temp = atoi(line[1]);

printf("temp is %d\n ",temp);
temp2 = temp + 5;
printf("temp2 is %d\n ",temp2);

return 0;
}

Then on compile,
gcc -Wall getloc_val.c
getloc_val.c: In function `main':
getloc_val.c:17: warning: implicit declaration of function `atoi'

The book I'm refering to mentions that I can do this but why am I
getting the implicit warning ?

Implict function declarations were legal under the c89/c90 standard.
The function had to return int and not be a variadic function. As
atoi() fits that, it's ok for a compiler conforming to that standard,
but bad practice. It's not legal under c99.

The compiler is allowed to issue any diagnostics it wants, as long as
it does the ones it must (in conforming mode). Compilers will often
issue diagnostics (a warning is a diagnostic for many compilers) for
things the designers thought might be programmer errors. Leaving out
the header is one such.




Brian
 
P

ptq2238

Thanks all for the advice.
I've done some further investigation using strtol and have modified my
program as such

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

#define LINESIZE 10

int main()
{
char line[LINESIZE];
char *lptr;
int temp;

printf("Please enter a letter and a value: ");
fgets(line, LINESIZE, stdin);

temp = strtol(line, &lptr, 0);

printf("The original string was %s\n",line);
printf("The numeric portion is %ld\n",temp);

return 0;
}

After compiling, I ran the program
with these results:

Please enter a letter and a value: 123qwe
The original string was 123qwe
The numeric portion is 123

Please enter a letter and a value: qwe123
The original string was qwe123
The numeric portion is 0

strltol seems to work when I enter numbers first then chars but not
the other way around.

Now I'm confused in how I can use strtol on the 2nd example, ie qwe123
and extract the numeric portion, which was based on my original
intentions of getting a character then a numeric from a string.
Have I misunderstood the strtol function ?
Pat
 
R

Richard Heathfield

(e-mail address removed) said:
Thanks all for the advice.
I've done some further investigation using strtol and have modified my
program as such
temp = strtol(line, &lptr, 0);

After compiling, I ran the program
with these results:

Please enter a letter and a value: 123qwe
The original string was 123qwe
The numeric portion is 123

Please enter a letter and a value: qwe123
The original string was qwe123
The numeric portion is 0

strltol seems to work when I enter numbers first then chars but not
the other way around.

Yeah - it's okay as long as it has numbers, but it stops when it runs
out. :)
Now I'm confused in how I can use strtol on the 2nd example, ie qwe123
and extract the numeric portion, which was based on my original
intentions of getting a character then a numeric from a string.
Have I misunderstood the strtol function ?

Yes. First plough your way through the non-numeric stuff, capturing it
if you desire, but in any case ploughing through it. Once you hit a
digit (or a '-' character, if you like negative numbers), call strtol.

Useful function in <ctype.h>: isdigit()
 
C

CBFalconer

.... snip ...

strltol seems to work when I enter numbers first then chars but
not the other way around.

Now I'm confused in how I can use strtol on the 2nd example, ie
qwe123 and extract the numeric portion, which was based on my
original intentions of getting a character then a numeric from a
string. Have I misunderstood the strtol function ?

Yes. strtol starts at the beginning. It can't extract a number
from chars, so it fails. It will skip leading blanks only.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
 
F

Flash Gordon

Richard Heathfield wrote, On 20/04/07 12:37:
(e-mail address removed) said:

temp should be of type long when using strtol. You will have problems if
it is of type int and the value read is too large to fit in an int.

Yes. First plough your way through the non-numeric stuff, capturing it
if you desire, but in any case ploughing through it. Once you hit a
digit (or a '-' character, if you like negative numbers), call strtol.

Useful function in <ctype.h>: isdigit()

Also consider how you should handle things like "A-B-23".
 
K

Keith Thompson

Flash Gordon said:
Richard Heathfield wrote, On 20/04/07 12:37:
(e-mail address removed) said: [...]
Now I'm confused in how I can use strtol on the 2nd example, ie qwe123
and extract the numeric portion, which was based on my original
intentions of getting a character then a numeric from a string.
Have I misunderstood the strtol function ?
Yes. First plough your way through the non-numeric stuff, capturing
it if you desire, but in any case ploughing through it. Once you hit
a digit (or a '-' character, if you like negative numbers), call
strtol.
Useful function in <ctype.h>: isdigit()

Also consider how you should handle things like "A-B-23".

And "123xyz456". You probably just want to return 123, but your
specification should cover all cases.
 
F

Francine.Neary

(e-mail address removed) wrote:
But you don't want to use atoi(), anyway. It has a few problems, because
its error handling is not so much bad as non-existent. Use strtol()
instead; you'll find it declared in <stdlib.h> as well.

But annoyingly there's no strtoi(), so you have to first do strtol()
then cast down to int. Plus strtol has tedious extra parameters to
pass.
 
B

Basu

hi,


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

#define LINESIZE 4

int main()
{
char line[LINESIZE];
int temp,temp2;

printf("Please enter a letter and a value: ");
fgets(line, LINESIZE, stdin);

printf("This line was entered: %s\n",line);

printf("line[0] is %c\n ",line[0]);
printf("line[1] is %c\n ",line[1]);
temp = atoi(&line[1]);

printf("temp is %d\n ",temp);
temp2 = temp + 5;
printf("temp2 is %d\n ",temp2);

return 0;

}

you have to add a #include <stdlib.h> bcz you are using linb function
called atoi
and you have to pass address inside the atoi ; like temp =
atoi(&line[0]);

regards
basavaraj
 
R

Richard Bos

But annoyingly there's no strtoi(), so you have to first do strtol()
then cast down to int. Plus strtol has tedious extra parameters to
pass.

Those aren't tedious; one of those _is_ the error handling, and the
other one can be made to do useful work, as well.

Richard
 

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,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top