Home > Enterprise >  Homework, write a function that converts a string of digits into an integer
Homework, write a function that converts a string of digits into an integer

Time:09-21

I know I could have found the code page on the Internet easily enough for that function, but I want to know why, after passing the 10 digit array, the expected result doesn't act like the previous ones.

#include <stdio.h>

int xstraylen(char *arr) {
    int len;
    
    for (len = 0; *(arr   len) != '\0'; len  ) {
        //printf("%c ", *(arr   len));
    }
    return len;
}

int str_into_int(char *str) {
    int power = 10, len, number;
    long int value = 0;
    
    len = xstraylen(str);
    printf("\n%d\n", len);

    for (int index = 0; index < len; index  ) {
        number = (int)(*(str   index) - 48);
        value  = number;
        value *= power;
        printf("-%d- %d %d ", index, number, value);
    }

    value /= power;

    return value;
}

int main() {    
    char *str = "1234567890";  
    int value;
    
    value = str_into_int(str);
    printf("\n\n%d", value);

    return 0;
}

Output

10

-0- 1 10 -1- 2 120 -2- 3 1230 -3- 4 12340 -4- 5 123450 -5- 6 1234560 -6- 7 12345670 -7- 8 123456780 -8- 9 1234567890 -9- 0 -539222988 

-53922298

CodePudding user response:

Your code does not work for 10 digit numbers because you always multiply value by 10 in the loop after adding the digit and divide it at the end. For a 10 digit number, the last multiplication causes an arithmetic overflow on your platform where both int and long probably have 32 bits.

You should multiply value before adding the digit and remove the final division:

int str_into_int(char *str) {
    int power = 10, len, number;
    long int value = 0;
    
    len = xstraylen(str);
    printf("\n%d\n", len);

    for (int index = 0; index < len; index  ) {
        value *= power;
        number = (int)(*(str   index) - 48);
        value  = number;
        printf("-%d- %d %ld ", index, number, value);
    }
    return value;
}

Note that the code can be further simplified and modified to handle larger values and detect overflow:

#include <limits.h>
#include <stdio.h>

unsigned long long int str_into_int(const char *str) {
    unsigned long long int value = 0;

    for (int i = 0; str[i] >= '0' && str[i] <= '9'; i  ) {
        unsigned int digit = str[i] - '0';
        if (value > ULLONG_MAX / 10 ||
            (value == ULLONG_MAX / 10 && digit > ULLONG_MAX % 10)) {
                printf("conversion exceeds range of unsigned long long\n");
                return ULLONG_MAX;
            }
        value = value * 10   digit;
    }
    return value;
}

void test(const char *str) {
    printf("%s -> %llu\n", str, str_into_int(str));
}

int main() {
    test("1234567890");
    test("12345678901234567890");
    test("18446744073709551615");
    test("18446744073709551616");
    test("123456789012345678901234567890");
    return 0;
}

Output:

1234567890 -> 1234567890
12345678901234567890 -> 12345678901234567890
18446744073709551615 -> 18446744073709551615
conversion exceeds range of unsigned long long
18446744073709551616 -> 18446744073709551615
conversion exceeds range of unsigned long long
123456789012345678901234567890 -> 18446744073709551615

CodePudding user response:

Your compiler considers the type long int as having the same range of values as the type int.

In this expression statement

value *= power;

there an overflow occurs when value is equal to 1234567890.

Change the logic of the for loop the following way

for (int index = 0; index < len; index  ) {
    value *= power;
    number = *(str   index) - '0';
    value  = number;
    printf("-%d- %d %ld ", index, number, value);
}

and remove this statement

value /= power;

Bear in mind that your function does not process a sign mark.

Take into account the function xstraylen should be declared the following way

size_t xstraylen( const char *arr ) {
    size_t len = 0;
    
    while ( *( arr   len ) )   len;

    return len;
}

CodePudding user response:

I would use the Horner's rule to compute the value of an integer, like this.

#include <stdio.h>
int main(void)
{
   char *ns="328327", *p=ns;
   int valn = 0;
   while(*p) valn=valn*10 (*p  -'0');
   printf("%d\n", valn);
   return 0;
}

Depending on what you want to do, you must take care and check not to produce overflow, the input to be correct, etc. But this is the simplest idea I can imagine for your problem.

  • Related