I have to capitalize the first letter of every word (words are separated by a space) into a given array of char. I wrote the code but I can't figure out why it's not working nor displaying anything in output.
Here's the code:
void LetterCapitalize(char *str) {
char *str2;
int i = 0;
str2[i] = toupper(str[0]);
i ;
while (str[i]) {
if (str[i] == ' ') {
str2[i] = str[i];
str2[i 1] = toupper(str[i] 1);
i = 2;
} else {
str2[i] = str[i];
i ;
}
}
printf ("%s", str2);
}
And here's the main:
int main(void) {
char stringa[16] = "some string here";
LetterCapitalize(stringa);
return 0;
}
CodePudding user response:
For starters this array
char stringa[16] = "some string here";
does not contain a string because it does not have a space to accommodate the terminating zero character '\0'
of the string literal used as an initializer.
It would be better to declare it the following way without explicit specifying its size
char stringa[] = "some string here";
So this while loop
while (str[i])
can invoke undefined behavior.
Also you are using the uninitialized pointer str2
.
char *str2;
//...
str2[i] = toupper (str[0]);
that again invokes undefined behavior.
Pay attention to that a passed string can contain more than one space between words and moreover can contain leading and trailing spaces. So this if statement also can invoke undefined behavior due to skipping the terminating zero character '\0'
of the source string
if (str[i] == ' ')
{
str2[i] = str[i];
str2[i 1] = toupper (str[i] 1);
i = 2;
}
Hence your approach is in general wrong.
Such a function should return the modified source string.
Instead of the for loop it is better to use standard C functions strspn
and strcspn
.
Here is a demonstration program.
#include <string.h>
#include <stdio.h>
#include <ctype.h>
char * LetterCapitalize( char *s )
{
const char *delim = " \t";
for (char *p = s; *p; p = strcspn( p, delim ) )
{
p = strspn( p, delim );
if (*p) *p = toupper( ( unsigned char )*p );
}
return s;
}
int main( void )
{
char stringa[] = "some string here";
puts( stringa );
puts( LetterCapitalize( stringa ) );
}
The program output is
some string here
Some String Here
CodePudding user response:
There are multiple problems:
- The string defined in
main
is not null terminated because it has exactly 16 characters. It is safer to omit the array length and let the compiler compute it from the initializer, including a null terminator:
char stringa[] = "some string here";
str2
is uninitialized: storing characters to it has undefined behavior. You could instead either modify the argument string in place or allocate a copy and modify that.the logic in
LetterCapitalize
is risky: you assume that words are separated by a single space and that the string does not end with a space.the
char
argument totoupper()
should be cast as(unsigned char)
to avoid undefined behavior on negativechar
values on platforms where the typechar
is signed by default.
Here is a modified version:
#include <ctype.h>
#include <stdio.h>
char *LetterCapitalize(char *str) {
unsigned char c, last = ' ';
// uppercase characters that follow a space or at the start of the string
for (size_t i = 0; (c = str[i]) != '\0'; last = c, i ) {
if (last == ' ')
str[i] = toupper(c);
}
return str;
}
int main() {
char stringa[] = "some string here";
puts(LetterCapitalize(stringa));
return 0;
}