Logan Darby Logan Darby - 3 months ago 8
C Question

C: Can reverse array of chars, but not string

I made a simple program to reverse a string in C. Here is my code:

#include <stdio.h>

int main(){
char istring[] = {'f','o','o','b','a','r'};

char revstring[sizeof(istring)];

for(int i = 0; i < sizeof(istring); i++){
int cplace = sizeof(istring)-i-1;
revstring[cplace] = istring[i];
}
printf("%s",revstring);
return 0;
}


and my result is, as expected
raboof
.

Now, if I swap
char istring[] = {'f','o','o','b','a','r'};
, with
char istring[] = "foobar";
, I get nothing as my output. What's wrong?

Thanks in advance.

(Sorry if this is a total newbie question)

Answer

In C, a string is a null terminated array of characters. In your original program, istring is not a string but an array of characters with no null byte at the end.

While you successfully reverse the characters, revstring is not a string because there is no terminating null byte at the end. As such, when you attempt to print it as a string using the %s format specifier for printf, it searches past the end of the array. Reading beyond the bounds of an array is undefined behavior.

One of the ways undefined behavior can manifest itself is that the program appears to work properly. In your case, you got "lucky" and got the expected result.

When you define istring as istring[] = "foobar"; you initialize it with a string constant which contains a null terminating byte. So this definition is actually one byte larger then the prior one.

When you reverse the characters, you're actually including the null byte. So the resulting array contains the null byte first followed by the other characters. Then when you print it, the null byte is seen first so what you have is an empty string.

In your loop, use strlen(istring) instead of sizeof(istring) as the upper bound. Then add the null byte at the end.

char istring[] = "foobar";
char revstring[sizeof(istring)];

for(int i = 0; i < strlen(istring); i++){
    int cplace = strlen(istring)-i-1;
    revstring[cplace] = istring[i];
}
revstring[strlen(istring)] = '\0';

If you define istring as an array of characters, you need to allocate an extra byte to revstring and keep sizeof when checking the upper bound:

char istring[] = {'f','o','o','b','a','r'};
char revstring[sizeof(istring)+1];

for(int i = 0; i < sizeof(istring); i++){
    int cplace = sizeof(istring)-i-1;
    revstring[cplace] = istring[i];
}     
revstring[sizeof(istring)] = '\0';
Comments