Forums

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • FAQ
  • Login
  • Register
  • Board index Assistance Portage & Programming
  • Search

gcc 3.4.4/5 C++ string/toupper (Solved)

Problems with emerge or ebuilds? Have a basic programming question about C, PHP, Perl, BASH or something else?
Post Reply
Advanced search
11 posts • Page 1 of 1
Author
Message
jmack1010
Tux's lil' helper
Tux's lil' helper
Posts: 93
Joined: Sun Jan 25, 2004 6:19 pm
Location: University of Cincinnati, Oh

gcc 3.4.4/5 C++ string/toupper (Solved)

  • Quote

Post by jmack1010 » Sat Dec 31, 2005 11:03 pm

I am having a very basic, but annoying problem with the function toupper and strings.
char *temp = new char[10];
temp="question";
while (*temp != '\0'){
if(islower(*temp))
*temp=toupper(*temp);
temp++;
}
It compiles, but the string temp is empty instead of capitalized. I would greatly appreciate any insight. Thank you.

Joe
Last edited by jmack1010 on Mon Jan 09, 2006 9:19 pm, edited 1 time in total.
Top
dmitchell
Veteran
Veteran
User avatar
Posts: 1159
Joined: Sat May 17, 2003 4:51 pm
Location: Austin, Texas

  • Quote

Post by dmitchell » Sat Dec 31, 2005 11:54 pm

Code: Select all

char* temp = new char[10];
temp = "question";
temp = "question" doesn't fill the space you've allocated, it makes temp point to a new stack allocated character array. In any case, you should be using the standard library.

Code: Select all

#include <algorithm>
#include <string>

inline void make_upper_case( std::string& s )
{ std::transform( s.begin(), s.end(), s.begin(), toupper ); }
Your argument is invalid.
Top
jmack1010
Tux's lil' helper
Tux's lil' helper
Posts: 93
Joined: Sun Jan 25, 2004 6:19 pm
Location: University of Cincinnati, Oh

  • Quote

Post by jmack1010 » Sun Jan 01, 2006 2:48 am

Thank you for you quick and knowledgeable response. I am pretty new to C++ and I do not know how to get your function to work correctly.

I included the header files:
#include <string>
#include <algorithm>
#include <cstdlib>
#include <iostream>

I pass a string *temp to make_upper_case(string &s) like:
temp=make_upper_case(temp);

However, is that function complete? Or how would I modify it to capitalize the string?

This is the error I get when I try to compile the code.
main.cc:12: error: no matching function for call to `transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unknown type>)'
main.cc: In function `int main()':
main.cc:28: error: invalid initialization of reference of type 'std::string&' from expression of type 'char*'
main.cc:12: error: in passing argument 1 of `void make_upper_case(std::string&)'
main.cc:24: warning: unused variable 'cap'
make: *** [main.o] Error 1
Thank you for your help and sorry for my ignorance.

Joe
Top
dmitchell
Veteran
Veteran
User avatar
Posts: 1159
Joined: Sat May 17, 2003 4:51 pm
Location: Austin, Texas

  • Quote

Post by dmitchell » Sun Jan 01, 2006 3:49 am

It looks like you're still trying to use character arrays to represent strings--don't. Use std::string, the string class provided by the standard library. You should probably get a copy of the book Accelerated C++, by Koenig and Moo. It's the best way to learn C++.

As written, make_upper_case capitalizes an existing string. For example:

Code: Select all

std::string s( "question" );
make_upper_case( s ); // s is "QUESTION"
If you want a function that creates a new string, use the following:

Code: Select all

inline std::string make_upper_case_copy( std::string const& in )
{
  std::string out( in );
  std::transform( out.begin(), out.end(), out.begin(), toupper );
  return out;
}
For example:

Code: Select all

std::string s( "question" );
char* c = "answer";

std::string upper = make_upper_case_copy( s ); // upper is "QUESTION"
upper = make_upper_case_copy( c ); // upper is "ANSWER"
upper = make_upper_case_copy( "question" ); // upper is "QUESTION" 
Your argument is invalid.
Top
jmack1010
Tux's lil' helper
Tux's lil' helper
Posts: 93
Joined: Sun Jan 25, 2004 6:19 pm
Location: University of Cincinnati, Oh

  • Quote

Post by jmack1010 » Wed Jan 04, 2006 9:59 pm

dmitchell,

Thank you again for your prompt response. I think that I confused what I was actually doing.
This is what I am acutally doing.

Instead of creating a static string s("string");

I am:
char * response=new char[10];
cout << "prompt user for entry.\n"
Then cin>>response;
response=make_upper_case(response);
I don't think you can use transform() in this instance. I also don't believe I can use a string in order to enter the characters from the cin. I, however, am not sure. I did purchase Accelerated C++ as it is apparent I need a better reference than I have currently.

If you know why my original code would not capitalize the string please let me know. I appreciate any help.

Thanks,

Joe
Top
int2str
Guru
Guru
User avatar
Posts: 362
Joined: Mon Sep 29, 2003 7:45 pm

Re: gcc 3.4.4/5 C++ string/toupper

  • Quote

Post by int2str » Wed Jan 04, 2006 10:59 pm

jmack1010 wrote:I am having a very basic, but annoying problem with the function toupper and strings.
char *temp = new char[10];
temp="question";
while (*temp != '\0'){
if(islower(*temp))
*temp=toupper(*temp);
temp++;
}
It compiles, but the string temp is empty instead of capitalized. I would greatly appreciate any insight. Thank you.

Joe
This is not a complete program.
I assume at one point after that you do a " cout << temp << endl;" or similar.

As others have recommended, you should really use std::string's instead of char*. But you still want an answer as to why your code snipped doesn't work.

What you need to do to figure this out is read your program in "english". Understand what the code you wrote does and compare it to what you would like it to do. If that doesn't make the problem obvious, get out a piece of paper and write out what you think the value of the variables you use is during the iterations. Or better, use a debugger (like gdb) and step through your code.

Let's start by using the "English translation" approach.
Your program in "english"

1. Allocate 10 characters in memory and and use the variable "temp" to point to the new space.
2. Assign "question" to the space allocated at "temp" location in memory.
3. Advance "temp" as long as "temp" doesn't point to an empty character, check if the character it points to is lower case and make it upper case if so.

Now if you read point 3 carefully, you'd notice that we're advancing "temp" until it points to a null character. Which means in other words that after the loop, temp points to a null character. So printing temp at this point will indeed print nothing.

You have another fundamental problem however...
The line temp = "question"; is not valid at this point. You cannot assign char[]'s in this way. What this line does is create a temporary space in memory and point temp to it. So "question" is not placed into the 10 bytes you allocated but a different space in memory instead. This also leads to the fact that you can never delete the original 10 bytes any more and thus your program leaks memory.

You would have noticed the memory leak if you would have tried to delete temp. Which brings me to another point which is: Always "delete" what you "new"!

To fix all your mistakes, write the program like so:

Code: Select all

#include <iostream>

using namespace std;

int main()
{
    char *temp = new char[10];
    strcpy( temp, "Question\0" );

    char *p = temp;
    while( *p != 0 )
        *p = toupper( *p++ );

    cout << temp << endl;
    delete [] temp;
}
But as others mentionen, if you really wan't to write (modern) "C++", and not just plain old "C", try it like so:

Code: Select all

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    string s = "Question";

    transform( s.begin(), s.end(), s.begin(), (int(*)(int))toupper );

    cout << s << endl;
}
But no matter what progamming language you use or which language facilities you try. Always use your head and familiarize yourself with "bench testing" and make sure you understand what you write.

Cheers,
Andre
Adpot an unanswered post today!
Top
dmitchell
Veteran
Veteran
User avatar
Posts: 1159
Joined: Sat May 17, 2003 4:51 pm
Location: Austin, Texas

  • Quote

Post by dmitchell » Wed Jan 04, 2006 11:05 pm

Here's a complete working program.

Code: Select all

#include <algorithm>
#include <iostream>
#include <string>
#include <cctype>

inline void make_upper_case( std::string& s )
{ std::transform( s.begin(), s.end(), s.begin(), ::toupper ); }

int main()
{
  std::cout << "Please enter your first name: ";

  std::string name;
  std::cin >> name;

  make_upper_case( name );
  std::cout << "Hello, " << name << "!" << std::endl;
  return 0;
}

You should be able to compile and run the above.
I did purchase Accelerated C++
Great! It's a wonderful book that will serve you well. Have a look at Chapter 1 to see how to use std::string.
If you know why my original code would not capitalize the string please let me know.
See int2str's explanation.
Your argument is invalid.
Top
jmack1010
Tux's lil' helper
Tux's lil' helper
Posts: 93
Joined: Sun Jan 25, 2004 6:19 pm
Location: University of Cincinnati, Oh

  • Quote

Post by jmack1010 » Mon Jan 09, 2006 7:53 pm

Thank you for you prompt responses. I apologize for not responding quicker, however, I have been very busy. I did get the code working thanks to both of your help. I have one final question though. I would get an error when I called transform function. That error message is in my original response. After I cast toupper as int2str suggested:
transform( s.begin(), s.end(), s.begin(), (int(*)(int))toupper );
the compiler error went away. Why must I cast a string as an int(*)int. I don't understand exactly what is going on.

Thanks again,

Joe
Top
int2str
Guru
Guru
User avatar
Posts: 362
Joined: Mon Sep 29, 2003 7:45 pm

  • Quote

Post by int2str » Mon Jan 09, 2006 8:41 pm

jmack1010 wrote:After I cast toupper as int2str suggested:
transform( s.begin(), s.end(), s.begin(), (int(*)(int))toupper );
the compiler error went away. Why must I cast a string as an int(*)int. I don't understand exactly what is going on.
The problem is that there are multiple versions of the std::toupper function defined in the STL. They are templated and use the type of the argument and return type to resolve which templated function to use. When the function is passed as an argument, without an obvious parameter, the compiler does not know how to resolve the template. Putting in the cast indicates to the compiler which parameter format to use.

Alternatively you can use dmitchell's solution and use the C-style function which is not part of the STL namespace like so:

Code: Select all

std::transform( s.begin(), s.end(), s.begin(), ::toupper );
Note the leading "::" to indicate global namespace and the lack of a cast.

Hope that explains it.

Cheers,
Andre
Adpot an unanswered post today!
Top
jmack1010
Tux's lil' helper
Tux's lil' helper
Posts: 93
Joined: Sun Jan 25, 2004 6:19 pm
Location: University of Cincinnati, Oh

  • Quote

Post by jmack1010 » Mon Jan 09, 2006 9:19 pm

Thanks for all the help.

Joe
Top
TheDebugger
Apprentice
Apprentice
User avatar
Posts: 159
Joined: Tue Aug 30, 2005 7:15 pm
Location: Germany

  • Quote

Post by TheDebugger » Mon Jan 09, 2006 9:54 pm

Why must I cast a string as an int(*)int. I don't understand exactly what is going on.

Code: Select all

(int(*)(int))toupper
is a cast to a specific prototype of toupper (a pointer to a function that takes an int and returns an int). Buried deep within the standard library is another toupper() funtion with a different signature:

Code: Select all

template<typename _CharT> _CharT toupper(_CharT, const locale&); 
The pointer-to-function style cast makes sure that the compiler uses the one without the locale :)
Top
Post Reply

11 posts • Page 1 of 1

Return to “Portage & Programming”

Jump to
  • Assistance
  • ↳   News & Announcements
  • ↳   Frequently Asked Questions
  • ↳   Installing Gentoo
  • ↳   Multimedia
  • ↳   Desktop Environments
  • ↳   Networking & Security
  • ↳   Kernel & Hardware
  • ↳   Portage & Programming
  • ↳   Gamers & Players
  • ↳   Other Things Gentoo
  • ↳   Unsupported Software
  • Discussion & Documentation
  • ↳   Documentation, Tips & Tricks
  • ↳   Gentoo Chat
  • ↳   Gentoo Forums Feedback
  • ↳   Duplicate Threads
  • International Gentoo Users
  • ↳   中文 (Chinese)
  • ↳   Dutch
  • ↳   Finnish
  • ↳   French
  • ↳   Deutsches Forum (German)
  • ↳   Diskussionsforum
  • ↳   Deutsche Dokumentation
  • ↳   Greek
  • ↳   Forum italiano (Italian)
  • ↳   Forum di discussione italiano
  • ↳   Risorse italiane (documentazione e tools)
  • ↳   Polskie forum (Polish)
  • ↳   Instalacja i sprzęt
  • ↳   Polish OTW
  • ↳   Portuguese
  • ↳   Documentação, Ferramentas e Dicas
  • ↳   Russian
  • ↳   Scandinavian
  • ↳   Spanish
  • ↳   Other Languages
  • Architectures & Platforms
  • ↳   Gentoo on ARM
  • ↳   Gentoo on PPC
  • ↳   Gentoo on Sparc
  • ↳   Gentoo on Alternative Architectures
  • ↳   Gentoo on AMD64
  • ↳   Gentoo for Mac OS X (Portage for Mac OS X)
  • Board index
  • All times are UTC
  • Delete cookies

© 2001–2026 Gentoo Foundation, Inc.

Powered by phpBB® Forum Software © phpBB Limited

Privacy Policy

 

 

magic