Reputation: 39
I know this question was asked here several times. I followed methods mentioned like initialize variable start
(int start = 0
), or typecast it to int
in printf
statement.
But these methods do not help. So I open up this post to ask this question again.
My program is to return a substring from a user input source string. My method works. Only printf
doesn't work.
I write up this method.
char *GetSubstring(const char source[], int start, int count, char result[])
{
if ((size_t)start > strlen(source)) {
*result = 0;
} else {
if ((size_t)(start + count) > strlen(source)) {
count = strlen(source) - start;
}
while (start > 0) {
source++;
start--;
}
*(result + count) = 0;
while ( count > 0 || *(source + count) != 0 ) {
count--;
*(result + count) = *(source + count);
}
}
return(result);
}
If I hard code all parameters, the print statements work fine.
int main(void)
{
char source[100] = "abcdefg";
char result[100];
int start = 2;
int count = 3;
printf("%s %d %d\n", source, start, count); //all correct
printf("%s %d %d %s\n", source, start, count,
GetSubstring(source,start,count,result));//all correct
return 0;
}
However if I get parameters from user input. 'start' in 1st printf
statement prints out correctly. But it prints out as garbage in the second printf
statement. Other parameters print out correct.
int main(void)
{
char source[100];
char result[100];
int start = 0;
int count = 0;
printf("enter source\n");
fgets(source, 100, stdin);
source[strcspn(source, "\n")] = '\0';
printf("enter start and count\n");
scanf("%d%d", &start, &count);
printf("%s %d %d\n", source, start, count); //all correct
//'start' print out as 1650524162, rest parameters correct
printf("%s %d %d %s\n", source, start, count,
GetSubstring(source,start,count,result));
return 0;
}
The problem may have to do with type casting (size_t)start
in my method GetSubstring
. But I need to do that for comparison with strlen(source)
.
Please let me know any suggestions. Thank you.
Upvotes: 2
Views: 96
Reputation: 23822
The problem is not the size_t
cast though you could make those variables size_t
and avoid casting altogether, like @klutt sugested, and use %zu
format specifier in printf
and scanf
.
The issue you complain about lies in this cycle:
while ( count > 0 || *(source + count) != 0 )
{
count--;
*(result + count) = *(source + count);
printf("%s %d %d\n", source, start, count);
}
As you use ||
in the condition, count
will be allowed to be negative, which in term allows for negative indexing of source
which in term invokes undefined behavior.
Another problem which is not apparent in the test case is the limit case, if you provide the parameters 2
and 5
, the result should be cdefg
and it's not, the conditon is not met and the cycle is never executed.
I believe what you need is:
while ( count > 0 && *(source + count - 1) != 0 ) { /*...*/ }
^^ ^^^
AFAICT that second condition is unneeded anyway so you could remove it and have only:
while ( count > 0) { /*...*/ }
Upvotes: 1