I'm trying to invert the case of some strings, and I did it, but I have some extra characters in my return, is it a memory problem? Or because of the length?
char* invertirCase(char* str){
int size = 0;
char* iterator = str;
while (*iterator != '\0') {
size ;
iterator ;
}
char* retorno = new char[size];
for (int i = 0; i < size; i ) {
//if capital letter:
if (str[i] < 96 && str[i] > 64) {
retorno[i] = str[i] 32;
}
// if lower case:
else if (str[i] > 96 && str[i] < 123) {
retorno[i] = str[i] - 32;
}
//if its not a letter
else {
retorno[i] = str[i];
}
}
return retorno;
}
For example, if I try to use this function with the value "Write in C"
it should return "wRITE IN c"
, but instead it returns "wRITE IN cýýýýÝݱ7ŽÓÝ"
and I don't understand where those extra characters are coming from.
PS: I know I could use a length function, but this is from school, so I can't do that in this case.
CodePudding user response:
add 1 to the size of the char array.
char* retorno = new char[size 1];
add a null-terminated string before returning retorno
.
retorno[size] = '\0';
CodePudding user response:
Your output string is not null-terminated
When you iterate through the input string, you increment size
until you reach null. That means the null is not copied to the output string. After you exit the loop, you should increment size
once more to capture the end.
As an aside, it's probably a good idea to constrain size
to some maximum (while(*iterator != '\0' && size < MAXSIZE)
) in case someone passes a non-terminated string into your function. If you hit the max size condition, you'd need to explicitly add the null at the end of your output.
CodePudding user response:
Your string should be null
terminated; which is what you are looking for when you get the initial size of the string. When you create the new string, you should allocated size 1
char
s of space, then retorno[size]
should be set to a null terminating character (i.e. '\0'
). When you attempt to print a char*
using printf
or cout
(or similar mechanisms), it will keep printing characters until it find the null terminating character, which is why you are getting the garbage values after your expected output.
On another note, c has helpful functions like std::islower
/ std::isupper
and std::tolower
/ std::toupper
CodePudding user response:
From what I can tell, there could be 2 things going on here:
- Like everyone here mentioned, the absence of a null terminating character (
'\0'
) at the end of your char array could be causing this. - It could be the way you are printing results of your
retorno
character string outside of yourinvertirCase()
function.
I tested out your function in C 14, C 17 and C 20 and it returned the correct result each time, both with the null terminating character at the end of the retorno
char array and without it.
Try printing your result inside of your function before returning it, to identify if this is being caused inside of your function or outside of it. Like so:
char* invertirCase(char* str){
// [... truncated code here]
for (int i = 0; i < size; i ) {
// [... truncated code here]
}
cout << " **** TESTING INSIDE FUNCTION ****" << endl;
cout << "-- Testing index iteration" << endl;
for (int i = 0; i < size; i ) {
cout << retorno[i];
}
cout << endl;
cout << "-- Testing iterator iteration" << endl;
for (char* iterator = retorno; *iterator != '\0'; iterator ) {
cout << *iterator;
}
cout << endl;
cout << "-- Testing advanced for loop" << endl;
for (char character : retorno) {
cout << character;
}
cout << " **** END TESTING ****" << endl;
cout << endl;
return retorno;
}
This way you could possibly identify both if the problem occurs inside of your function or if the problem is occurring because of the way you may be printing your result as well.