Is problem in function or main?

I am trying to change a letter in a string to an upper case version of the letter.

Function
1
2
3
4
5
6
7
8
9
10
11
12
void SetLetterUpper( string &letter,char character)
{
    for (int i = 0; i < letter.length(); i++)
    {
        if (letter[i] == character)
        {
            letter[i] = toupper(letter[i]);
        }
    }


}



Main
1
2
3
4
5
6
7
8
9
 

char name[] = "john jonah jameson, jr.";
    cout << "Before: " << name << endl;

    SetLetterUpper(name, 'j');
    cout << "After: " << name << endl;

    cout << endl;
You're trying to parse a char array instead of a string. Either change string &letter to char letter[] and letter.size() to sizeof(letter) or change name's typename to string.
Last edited on
To add to that, what is happening is when main calls SetLetterUpper, it creates a temporary std::string object from name because SetLetterUpper requires a string, and there is a 1-argument std::string constructor that takes a char*. This temporary value is passed to the function and manipulated. When the function returns, the original char* remains untouched, and that is what you are printing out.
> and letter.size() to sizeof(letter)
strlen(letter)
sizeof would give you the size of a pointer.

> This temporary value is passed to the function and manipulated.
You cannot bind a non-const reference to a temporaty.
The snip shouldn't compile.


@OP: http://www.cplusplus.com/forum/articles/40071/#msg218019
Last edited on
Wouldn't one also use strncmp()?
Does == work in C++ for comparing strings or letters?
@Stremik
If we're talking about cstring (char pointers) functions, almost all of them are made unnecessary if we're using C++'s std::string class instead.

C++ itself does not have == operator specifically for comparing char pointers in a logical way (it only compares the actual memory addresses).

std::string == operator does have operator overloading, to allow comparing an std::string to a char pointer or string literal, but does not have operator overloads for comparing std::string to character (char, not char*).

Ex:
1
2
3
4
5
6
#include <string>
int main() {
  std::string a = "h";
  char b = 'h';
  if (a == b) {}; // would not compile
}
Last edited on
I see. Thank you.
So than this modification:
1
2
char c = 'h';
char* b = &c;

would make your Example compile?

BTW It seems to me that the reason for which std::string == operator does not
have operator overloads for comparing std::string to character might be some
heredity that came from C or even something that has its roots in architecture
of a computer. Maybe the way memory is accessed?
Can you elaborate on this caveat.

Thank you.
Last edited on
I don't know why std::string doesn't have == overloads for char (or for that matter cannot be constructed from a char), it might just have been a conscious decision by the library writers to do so, but I don't see why it would cause problems, maybe someone else knows more.


You saying do this?
1
2
3
4
5
  std::string a = "h";
  char c = 'h';
  char* b = &c;

  (a == b);

It would compile, but smells like undefined behavior because char c isn't necessarily going to be null terminated.
Last edited on
You right!. There could be anything in memory right after that char variable.
Dang! I never thought that transitioning into C++ would actually make me go back
and think in C, thus reinforcing it in my memory even more. I like it!
I was sad about having to give up C.
i asked the question wrong, what i meant to say was i wanted to change all of the same characters.

i remembered that c strings end in the null operator '\0'

Here is my function, and it works! :D

FUNCTION:
1
2
3
4
5
6
7
8
9
10
11
12
void SetLetterUpper( char letter[],char character)
{
    for (int i = 0; i < '0' ;i++)
    {
        if (letter[i] == character)
        {
            letter[i] = toupper(letter[i]);
        }
    }


}


I thought the '\0' was to work but instead i changed it for '0', and the program did what i wanted it to do.

Can anyone clarify if the ending of c string is '\0' or '0'?
Last edited on
> Here is my function, and it works!
No, you suck at testing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

void SetLetterUpper( char letter[],char character)
{
    for (int i = 0; i < '0' ;i++)
    {
        if (letter[i] == character)
        {
            letter[i] = toupper(letter[i]);
        }
    }
}

int main(){
	char yell[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
	SetLetterUpper(yell, 'a');
	std::cout << yell << '\n';
}
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaa


> Can anyone clarify if the ending of c string is '\0' or '0'?
'\0'


The problem is that you threat `i' as it were the character.
`i' is an index, `letter[i]' is the character.
Last edited on
1
2
3
4
if (letter[i] == character)
        {
            letter[i] = toupper(letter[i]);
        }


letter[I], the index is compared to see if it is the same as character.
if it is the same as character it changes to uppercase.

But I don't know what I did wrong?
> for (int i = 0; i < '0' ;i++)
`i' is an index. It goes, 0, 1, 2, ....
It does not become '\0' at the end of the string.

letter[i] is a character. By instance, it goes 'h', 'e', 'l', 'l', 'o', '\0'
It becomes '\0' when you reach the end of the string.


So the loop may be for(int i=0; letter[i] not_eq '\0'; ++i)
1
2
3
4
5
6
void SetLetterUpper( char letter[30] , char character)
{
    for (int i = 0; i < strlen(letter) ; i++)
        if ((letter[i] == character)&&(islower(letter[i])))  
            /*update*/ letter[i]=toupper(letter[i]); 
}


This should work. Since you're working with character manipulation, I strongly suggest you use character arrays instead of strings, they're much easier to work with in this context.
Last edited on
line 5: statement has no effect.
line 4: useless check, toupper() works fine with characters that are not lowercase.

If you use string
1
2
3
4
5
6
]void SetLetterUpper(/* char[30] */ std::string &letter, char character)
{
    for (int i = 0; i < letter.size()/*strlen(letter)*/ ; i++)
        if (letter[i] == character)
            letter[i] = toupper(letter[i]); 
}
I don't see how that is so more complicated.
@ne555 I guess, its more portable, right? I mean, since some people, well atleast where I'm from, use Turbo C++, and strings aren't really support out of the box..
( ps - I'm an avid Code::Blocks user and completely against Turbo, but I don't even know why, but schools here have this unreasonable love for Turbo, and thus, along with them, all/most of the students..)
Topic archived. No new replies allowed.