George W.
George W.

Reputation: 39

printf doesn't always print correctly

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

Answers (1)

anastaciu
anastaciu

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) { /*...*/ }

Live demo

Upvotes: 1

Related Questions