Learning C and checking the reference from the GNU reference manual. I don't understand how is the maximum size that can be allocated to a char array defined in an exact way. In my test program when the allocated size for a string array is "small" it works fine but when it is "large" the program start behaving erratically. The compiler throws no errors when it gets compiled but during runtime, it is affecting the correctness of my program that uses strtok()
, missing some valid tokens in the result.
Taking as input (considering 5 an arbitrary "small" array size):
>> 5
>> 19 65 41 65 56
The sum output is 246 so it works well
But taking as input (considering 53 an arbitrary "large" array size):
>> 53
>> 19 65 41 65 56 74 76 71 29 44 45 9 66 37 59 6 71 8 30 29 41 31 96 86 11 14 29 24 17 65 88 23 21 49 31 96 72 39 83 96 96 63 44 72 85 38 5 11 70 36 90 49 76
The sum output is 2247 which is wrong (correct is 2647). This incorrectness holds for any "large" number of array_size
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
/*Array size is the amount of integers that will be introduced later. E.g: 5 (introducting 5 integers next) -> 3 4 5 6 7*/
/*The numbers are 1 <= n <= 1000 */
int array_size;
scanf("%d", &array_size);
printf("The array size you introduced is %d\n", array_size);
/* Given that the integers introduced can have at most 4 digits and they are separated by a whitespace character, array_size*5 is allocated */
char sentence[array_size * 5];
scanf("\n");
scanf("%[^\n]%*c", sentence);
char delimiter = ' ';
char *token;
token = strtok(sentence, &delimiter);
int sumResult;
printf("The token %d is %s\n", 1, token);
while (token != NULL) {
sumResult = sumResult atoi(token);
token = strtok(NULL, &delimiter);
printf("The token is %s\n", token);
}
printf("%d\n", sumResult);
}
CodePudding user response:
There are (at least) three errors in the program:
int sumResult;
leaves sumResult
uninitialized. It must be initialized to zero, as with int sumResult = 0;
.
strtok(sentence, &delimiter)
passes the address of a single character to strtok
. For the second parameter, strtok
expects a pointer to the first character of a string, meaning a sequence of characters terminating by a null character. Change the definition of delimeter
to char delimiter[] = " ";
and change both strtok
calls to strtok(sentence, delimiter);
.
printf("The token is %s\n", token);
is executed once when token
is a null pointer. For %s
, printf
should be passed a pointer to the first character of a string, not a null pointer. This can be remedied by moving this printf
to be the first line in the while
loop and deleting the prior printf("The token %d is %s\n", 1, token);
.
CodePudding user response:
int sumResult;
When sumResult
is not initialized, it does not have a determined value. In the language of the C standard, is value is indeterminate, meaning that the program may behave as if sumResult
has no fixed value at all; it may appear to have different values at different times. Further, in this program, using it without it being initialized results in the entire behavior of the program not being defined by the C standard.
int sumResult = 0;
In the C language object (variables) have different storage durations.
- Variables defined in the function scope have automatic storage duration and are not automatically initialized.
- Variables defined outside of any function (file scope) and variables defined in functions but declared as
static
have static storage duration and are automatically initialized (to zero or equivalent for their type) on program startup.
You can do it much easier:
int main(void)
{
/*Array size is the amount of integers that will be introduced later. E.g: 5 (introducting 5 integers next) -> 3 4 5 6 7*/
/*The numbers are 1 <= n <= 1000 */
size_t array_size;
if(scanf("%zu",&array_size) != 1) {/* error handling */}
printf("The array size you introduced is %zu\n", array_size);
int array[array_size];
/* Given that the integers introduced can have at most 4 digits and they are separated by a whitespace character, array_size*5 is allocated */
int sumResult = 0;
for(size_t num = 0; num < array_size; num )
{
if(scanf("%d", array num) != 1 ) {/* error handling */; break;}
sumResult = array[num];
}
printf("%d\n", sumResult);
}
https://godbolt.org/z/zoWz1cjc7
Your code "repaired"
int main(){
/*Array size is the amount of integers that will be introduced later. E.g: 5 (introducting 5 integers next) -> 3 4 5 6 7*/
/*The numbers are 1 <= n <= 1000 */
int array_size;
scanf("%d", &array_size);
printf("The array size you introduced is %d\n", array_size);
/* Given that the integers introduced can have at most 4 digits and they are separated by a whitespace character, array_size*5 is allocated */
char sentence[array_size * 5];
scanf("\n");
scanf("%[^\n]%*c", sentence);
char delimiter[] = " ";
char *token;
token = strtok(sentence, delimiter);
int sumResult = 0;
printf("The token %d is %s\n", atoi(token), token);
while (token != NULL) {
sumResult = sumResult atoi(token);
printf("The token is %s %d\n", token, atoi(token));
token = strtok(NULL, delimiter);
}
printf("%d\n", sumResult);
}