-2

I have a code line as follows,

char conv[20]="score: 34";

I want to extract the number(34) inside the 'conv' string and convert it into and integer. I used 'atoi' function. But it give 0 as the result.

printf("score: %d\n",atoi(conv)); //this prints 'score: 0'

Could someone help me to convert the number inside that string into an integer?

Nipuna Dilhara
  • 424
  • 2
  • 6
  • 18
  • 1
    Functions like `atoi()` only work if the string is a pure number. You must first find the number. You can do this using a function like [strpbrk(conv,"0123456789")](http://en.cppreference.com/w/cpp/string/byte/strpbrk). – Dúthomhas Oct 22 '17 at 06:17
  • 2
    And to get a little further in the weeds, you would need to include `+-` as chars that can begin the string to convert and check that the next character is `0-9`. Also recommend `strtol` instead of `atoi`, `atoi` provides no way to validate a successful conversion has taken place. – David C. Rankin Oct 22 '17 at 06:23
  • 6
    You could also do `sscanf(conv, "score: %d", &n);` if you know the string has that format. – Tom Karzes Oct 22 '17 at 06:32
  • [Why shouldn't I use `atoi()?`](https://stackoverflow.com/q/17710018/995714) – phuclv Oct 22 '17 at 09:11
  • @TomKarzes It works.. thanks.. – Nipuna Dilhara Oct 22 '17 at 16:04

2 Answers2

2

atoi() will return 0 if conversion cannot be performed. Look here.

The string "score: 34" cannot be converted to a valid int. So atoi() returns 0.

If there's nothing else after the 34 in your string, you could do

printf("score: %d\n",atoi(conv + 7));

This would give 34. conv + 7 points to the string "34". It is equivalent of conv + strlen("score: ").

Use of strtol() instead of atoi() might be better here.

You can find what exactly went wrong more easily with strtol().

You could use it like

long rv=strtol(conv, &ptr, 10);

where ptr is of type char * or just

rv=strtol(conv, NULL, 10);

If conv is "score: 34" here, 0 is returned and ptr will point to start of conv.

Note that strtol() returns a long and not an int.

If the range of int is less than that of long, you may want to check if the returned value is greater than the biggest int which is INT_MAX for signed int. INT_MAX is in limits.h.

If overflow occurred because of the number in string being too large to be represented in a long, errno will be set to ERANGE (it's in errno.h).

long rv=strtol(str, NULL, 10);
if(rv>INT_MAX || rv<INT_MIN || errno==ERANGE)
{
    perror("something is wrong.");
}
J...S
  • 5,079
  • 1
  • 20
  • 35
0

You are trying to use atoi which according to the documentation states:

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed and zero is returned.

So as you can understand, your code has an invalid conversion.

Here are some sample codes that will work:

  1. Correct use of atoi:

    char conv[20]="34";
    printf("score: %d\n",atoi(conv)); //this prints 'score: 34'
    
  2. Using strpbrk:

    char conv[20]="score: 34";
    char breakset[] = "0123456789";
    printf("score: %d\n",atoi(strpbrk(conv, breakset))); //this prints 'score: 34'
    
Dror Moyal
  • 398
  • 3
  • 11