Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different results when running the function multiple times - C

I've written a function and when I'm running it once it works perfectly, but when I'm running it multiple times with different inputs something goes wrong.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define MAX_SIZE 20

int SumStr(char *str) {
  int i = 0, j = 0, num = 0, tempnum = 0;
  char temp[MAX_SIZE];
  while (*(str + i) != 0) { //While not NULL - Checked
    while (((*(str + i)) >= 48) && ((*(str + i)) <= 57)) { //while str[i] is [0-9]
        *(temp + j) = *(str + i);
        ++j; ++i;
    }
    if (j != 0) {
        tempnum = atoi(temp);
        num = tempnum + num;
        tempnum = 0;
        j = 0;
    }
    ++i;
}
return num;
}

void Test3(char *arr, int sum)
{

int tempSum = SumStr(arr);
if (tempSum != sum)
{
    printf("Your Output is %d, Expected: %d (-3)\n", tempSum, sum);
}
}

void main() {

Test3("ax3b5mt11f", 19);
Test3("5$5$5", 15);
Test3("1234", 1234);
Test3("1$0!100", 101);
Test3("1$1!1", 3);
}

The purpose of the function, is to sum all the numbers within the string.

When I'm running the function once with this main (for example), it works perfectly;

void main() {
Test3("1$0!100", 101);
}

Output: num=101

But when the main runs the function multiple times with different inputs, the output is completely wrong.


The output from this main;

void main() {
Test3("ax3b5mt11f", 19);
Test3("5$5$5", 15);
Test3("1234", 1234);
Test3("1$0!100", 101);
Test3("1$1!1", 3);
}

Is;

Your Output is 6871, Expected: 15
Your Output is 6718, Expected: 1234
Your Output is 5024, Expected: 101
like image 402
Lior G. Avatar asked Feb 12 '26 12:02

Lior G.


2 Answers

One issue is that you do not terminate your temp-string with a '\0'-character before passing it to atoi. You could write:

temp[j] = '\0';  // or: *(temp + j) = '\0';
if (j != 0) { ...

Note that passing character sequence that is not correctly terminated with '\0' to a function that expects a (terminated) string yields undefined behaviour; that's probably what you observe then.

Second, if the last character of your input string is a digit, you increment i twice and thereby miss the string terminating character of the input. This again leads to undefined behaviour. To overcome this, you could check if you are at the end of the string before incrementing i:

    if (*(str + i) != 0) {
      ++i;
    }
like image 138
Stephan Lechner Avatar answered Feb 15 '26 13:02

Stephan Lechner


In addition to not terminating temp[j], you also skip the terminating character in str by incrementing i both in the inner loop and outer loop. When you skip the termination, it starts processing the next string [ or depending upon your compiler/OS, any old crap ].

btw, while (isdigit(str[i])) is not only more readable, portable and efficient than yours, it also makes the comment unnecessary.

like image 37
mevets Avatar answered Feb 15 '26 12:02

mevets



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!