You’ve tagged this as c++ but it seems like you’re using entirely c.. So I’ll answer this as if it’s c.
A segmentation fault occurs when you access memory that you don’t own. In this case you’re trying to print a character outside of the bounds of your string. (e.g. your string is len
characters long but you try to print character len+1
).
In your case this is happening because of your inner while loop. Consider the string abcd\0
.
For your outer while loop the case s[n] != '\0'
succeeds because s[n]
is 'a'
. We move then to your inner while loop. For all letters in your string abcd\0
the case s[n] != ' '
succeeds because none of the characters are a space. This means that your loop will continue to search for a byte that evaluates as a space character past the end of your string. Once you finally find one, if you finally find one you will try to print the character, which inevitably means that your program will segfault because it doesn’t own the memory it’s trying to access. If your program didn’t segfault it would actually continue to do this, because your algorithm doesn’t actually guarantee that you’ll ever find a stopping point. The only time it would was if you had a character and then the end of the string (e.g. a\0
or abc d\0
).
You have some correct ideas, but to fix this you need to re-evaluate how you want your loop to execute. For the outer loop, you’re using an incrementing variable to determine when to end your loop, consider changing this to a for loop:
for (int i = 0; s[i] != '\0'; ++i) {
}
This is essentially the same as before, just cleaner. The real issue is your inside loop. Consider what you want to do here. You could do this with an inner loop, but you’d need to recheck the same outer condition. Let’s try and find a solution that doesn’t do that. Starting with we don’t want to print spaces. This is a fairly simple addition:
for (int i = 0; s[i] != '\0'; ++i)
{
if (s[i] == ' ')
{
continue;
}
}
Using continue will ensure that we’ll restart the loop without running any of the rest of the code in the loop. We’ve also learend something interesting in this if: we’ve recently print a space. We can use this info if we track it so that we can print the next character (the initial). So let’s add a boolean to watch for that.
int printedSpace = 0; // In c++ this would be `bool printedSpace = false;`
for (int i = 0; s[i] != '\0'; ++i)
{
if (s[i] == ' ')
{
printedSpace = 1; // In c++ this would be `printedSpace = true;`
continue;
}
}
Now that we know we’re skipping space characters and that the next iteration we’ll remember that we’ve printed a space we can use this info to print the character. Also, just to back-check our previous condition, that we’ll stop at the end of the string ('\0'
) we only read one character at a time, and then restart the loop (continue
) so even if the last character in the string is ' '
(e.g. "abcd \0"
) we won’t try to execute the loop again. Anyways, adding the print:
int printedSpace = 0; // In c++ this would be `bool printedSpace = false;`
for (int i = 0; s[i] != '\0'; ++i)
{
if (s[i] == ' ')
{
printedSpace = 1; // In c++ this would be `printedSpace = true;`
continue;
}
else if (printedSpace)
{
printf("%c", toupper(s[i])); // Note that we're printing this character and not the next one
printedSpace = 0; // In c++ this would be `printedSpace = false;`
}
}
Two important things to notice here: first is that we reset printedSpace
back to false so that we don’t keep printing character, second is that if we have multiple spaces in a row it won’t break anything, we’ll just keep executing continue
until we find a non-space character. And frankly that’s it. We’ve guaranteed that our count will stop at '\0'
and we’re printing characters after spaces. As a bonus, since you already assume that the first character in the string is an initial, if you set printedSpace
to true before the beginning of the loop you will print the first character. This means you can remove the print above the loop. Just remember that you’re assuming this, but I could break it by inputting ' Rock Hilary'
. Of course you’ll just print ' RH'
, since the rest of the algorithm will work as intended.
1
solved My program is executing as expected but in the end I am an extra line called a segmentation fault near the output. Could someone see to it?