10

For some reason my C program is refusing to convert elements of argv into ints, and I can't figure out why.

int main(int argc, char *argv[])
{

    fprintf(stdout, "%s\n", argv[1]);

    //Make conversions to int
    int bufferquesize = (int)argv[1] - '0';

    fprintf(stdout, "%d\n", bufferquesize);
}

And this is the output when running ./test 50:

50

-1076276207

I have tried removing the (int), throwing both a * and an & between (int) and argv[1] - the former gave me a 5 but not 50, but the latter gave me an output similar to the one above. Removing the - '0' operation doesn't help much. I also tried making a char first = argv[1] and using first for the conversion instead, and this weirdly enough gave me a 17 regardless of input.

I'm extremely confused. What is going on?

alex
  • 479,566
  • 201
  • 878
  • 984
limasxgoesto0
  • 4,555
  • 8
  • 31
  • 38
  • I think you might mean `argv[1][0]` (type is `char`) <-- first character of first argument (after exec name). Of course, there is still no checking with that and there are better ways. Don't try to "cast away an error" (as `argv[1]` is typed as `char*`) because it often just doesn't work :-) –  Mar 19 '12 at 20:10

4 Answers4

51

Try using atoi(argv[1]) ("ascii to int").

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
12

argv[1] is a char * not a char you can't convert a char * to an int. If you want to change the first character in argv[1] to an int you can do.

int i = (int)(argv[1][0] - '0');

I just wrote this

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

int main(int argc, char **argv) {
    printf("%s\n", argv[1]);

    int i = (int)(argv[1][0] - '0');

    printf("%d\n", i);
    return 0;
}

and ran it like this

./testargv 1243

and got

1243
1
twain249
  • 5,666
  • 1
  • 21
  • 26
  • You dropped your reference to atoi... why? – FrankieTheKneeMan Mar 19 '12 at 20:21
  • @FrankieTheKneeMan I was never using atoi. you could use it if you want but my answer never had it. The answer from Scott Hunter uses it though. – twain249 Mar 19 '12 at 20:23
  • Why is it that you had to do `int i = (int)(argv[1][0] - '0');` as opposed to `int i = (int)(argv[1][0]);`? Why was the `- '0'` necessary? – nonsequiter Oct 27 '15 at 20:56
  • Because if your first character is '1', 1 in ascii is 49, so casting would return 49. You want to subtract by the first digit ('0' in ascii is 48), and then cast to get the correct answer. – pushkin Oct 31 '15 at 23:59
3

You are just trying to convert a char* to int, which of course doesn't make much sense. You probably need to do it like:

int bufferquesize = 0;
for (int i = 0; argv[1][i] != '\0'; ++i) {
   bufferquesize *= 10; bufferquesize += argv[1][i] - '0';
}

This assumes, however, that your char* ends with '\0', which it should, but probably doesn't have to do.

Stefan Marinov
  • 570
  • 4
  • 14
  • 1
    Actually it assumes the array of `char`s *that your `char *` points to* ends with `'\0'`. Whether the pointer "ends in `'\0'` (what would that mean anyway? that its representation ends in a 0 byte?) is not an issue. – R.. GitHub STOP HELPING ICE Mar 19 '12 at 22:03
  • Of, course. The sentence "a pointer to `char` ends with a certain symbol" just doesn't make sense. Thank you for the correction. :) – Stefan Marinov Mar 20 '12 at 01:02
2

(type) exists to cast types - to change the way a program looks a piece of memory. Specifically, it reads the byte encoding of the character '5' and transfers it to memory. A char* is an array of chars, and chars are one byte unsigned integers. argv[1] points to the first character. Check here for a quick explanation of pointers in C. So your "string" is represented in memory as:

['5']['0']

when you cast

int i = (int) *argv[1]

you're only casting the first element to an int, thus why you

The function you're looking for is either atoi() as mentioned by Scott Hunter, or strtol(), which I prefer because of its error detecting behaviour.

FrankieTheKneeMan
  • 6,645
  • 2
  • 26
  • 37