CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Sep 2003
    Posts
    54

    'const string' to 'char *'

    Hello !!

    How can I convert a 'const string' to 'char *' ?

    I have the following code:

    int validateXMLfile(char *xmlFile_name);

    int Processor::InsertOrder( const string file )
    {
    int error=0;
    error = validateXMLfile( file );
    if( error == 1 ) {
    cout << "\nERROR VALIDATING file: " << file << endl;
    return error;
    }
    else {
    cout << "Order VALIDATED against schema OK "<< endl;
    }

    }

    I get the following compiling error:
    Processor::InsertOrder (basic_string<char,
    string_char_traits<char>, __default_alloc_template<true, 0> >)':
    Processor.cc:586: cannot convert `const string' to `char *' for
    argument `1' to `validateXMLfile (char *)'

    Thanks!!

  2. #2
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    Change
    Code:
    int validateXMLfile(char *xmlFile_name);
    to
    Code:
    int validateXMLfile(const char *xmlFile_name);
    and call it:
    Code:
    error = validateXMLfile( file.c_str() );
    removing constness is almost always a bad idea...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  3. #3
    Join Date
    Sep 2003
    Posts
    54
    Thanks for your suggestion.

    The problem is that 'validateXMLfile' belongs to a dynamic library that I have to use and I cannot change.

    My code links with that library!!

  4. #4
    Join Date
    Jun 2003
    Location
    Gjøvik, Norway
    Posts
    204
    If we ignore the possibillity of using a const_cast<> (Don't do it!), you'll have to make a copy of the string and assign that one instead of the original.
    Code:
    int validateXMLfile(char *xmlFile_name);
    
    int Processor::InsertOrder(const string file)
    	{
    	int error = 0;
    
    	char* TempString = new char[file.size() + 1];
    	strcpy(TempString, file.c_str());
    
    	error = validateXMLfile(TempString);
    
    	delete[] TempString;
    	
    	if(error == 1)
    		{
    		cout << "\nERROR VALIDATING file: " << file << endl;
    		return error;
    		} 
    	else
    		{ 
    		cout << "Order VALIDATED against schema OK "<< endl; 
    		}
    
    	}
    It ain't pretty, but it works.

  5. #5
    Join Date
    Nov 2003
    Posts
    1,902
    Originally posted by Assmaster
    If we ignore the possibillity of using a const_cast<> ...
    const_cast<> only works on class objects.

    I would use a C-string off the stack - MAX_PATH should be large enough.

    gg

  6. #6
    Join Date
    Aug 2002
    Location
    United States
    Posts
    729
    I would use a C-string off the stack - MAX_PATH should be large enough.
    considering it's apparently a file name you're right but it's still better practice to use the string classes' length member and size it accordingly.

    *basically what assmaster has posted, which btw, i dont see why you say it isn't pretty assmaster, as far as i'm concerned it's just fine*

    and as a side note, i'd also pass the string by reference since it's const declared but what you gain in memory use by doing so you can lose in speed by dereferencing etc etc, just a matter of preference.

  7. #7
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    ... and then, when that's all working, track down the author of the library function and spend some time explaining the value of specifying "const" whenever possible...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  8. #8
    Join Date
    Jun 2003
    Location
    Gjøvik, Norway
    Posts
    204
    Originally posted by Codeplug
    const_cast<> only works on class objects.
    Well... You can cast away the const from the const char* returned by the std::string.c_str() function, but it cannot however be considered safe, so as I said: Don't do it!
    Originally posted by filthy_mcnasty
    *basically what assmaster has posted, which btw, i dont see why you say it isn't pretty assmaster, as far as i'm concerned it's just fine*
    What I meant was that it's not as pretty as it could be if the library author had used a const char* to pass in the filename. I this case it's the only (safe) solution, and therefore it's as good as it'll get!

  9. #9
    Join Date
    Aug 2000
    Location
    New Jersey
    Posts
    968
    IMHO, a more efficient and safer method would be to use a vector<char> type to pass to your function.
    Example:

    PHP Code:
        vector<charData_v(file .begin(), file .end());

        
    validateXMLfile(&Data_v[0]); 
    By using this method, you don't have to worry about deleting the data, and the variable gets allocated and initialized with the correct values all in one shot.
    David Maisonave
    Author of Policy Based Synchronized Smart Pointer
    http://axter.com/smartptr


    Top ten member of C++ Expert Exchange.
    C++ Topic Area

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449
    Originally posted by Axter
    IMHO, a more efficient and safer method would be to use a vector<char> type to pass to your function.
    Example:

    PHP Code:
        vector<charData_v(file .begin(), file .end());

        
    validateXMLfile(&Data_v[0]); 
    By using this method, you don't have to worry about deleting the data, and the variable gets allocated and initialized with the correct values all in one shot.
    The only problem I see is that the data is not null-terminated. You can either
    Code:
    Data_v.push_back('\0');
    before the call to validateXMLfile, or
    Code:
      #include <vector>
      #include <algorithm>
      std::vector<char> Data_v(file.length() + 1, 0)
      std::copy(file.begin(), file.end(), Data_v.begin());
      validateXMLfile(&Data_v[0]);
    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401
    Well... You can cast away the const from the const char* returned by the std::string.c_str() function, but it cannot however be considered safe, so as I said: Don't do it!
    Hmm, after all the reason why const_cast is part of the C++ language is that there are many C-libraries out there with bad interfaces (expecting a char * instead of a const char *).

    So if you are using const_cast here, you are using it exactly for the reason its creators had in mind.

    But if you don't mind the extra time spent on copying the string, don't use const_cast and stay on the safe side.

    BTW, your function
    Code:
    int Processor::InsertOrder( const string file )
    should most likely better be called
    Code:
    int Processor::InsertOrder( const string& file )
    as there is not much sense in passing a string by value if the function treats it as const anyways. Surprised nobody else pointed that out yet.

  12. #12
    Join Date
    Nov 2003
    Posts
    1,902
    Originally posted by Codeplug
    const_cast<> only works on class objects.
    Originally posted by filthy_mcnasty
    and as a side note, i'd also pass the string by reference...
    gg

  13. #13
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401
    Originally posted by Codeplug
    const_cast<> only works on class objects.
    Says who? I'm not very good at reading the standard, but a quick look through expr.const.cast did not reveal me anything that confirms your statement. Besides, the following compiles without any warning with g++.

    Code:
    #include <string>
    #include <stdio.h>
    
    void lousy_c_function( char * s )
    {
            printf( "%s\n", s );
    }
    
    int main()
    {
            const std::string mystring( "Hello World!" );
            lousy_c_function( const_cast<char*>( mystring.c_str() ) );
            return 0;
    }
    Originally posted by filthy_mcnasty
    and as a side note, i'd also pass the string by reference...
    Missed that...

  14. #14
    Join Date
    Aug 2002
    Location
    United States
    Posts
    729
    as i was alluding to though, when you pass by reference you really just have a programmer simplified pointer and the process of dereferencing it repeatedly can often be more time consuming than simply passing by value. but all that stuff is trivial and dependant on many other things so yeah, i'd still pass by reference.

  15. #15
    Join Date
    Nov 2003
    Posts
    1,902
    >> Say's who?
    Me! unfoturnately...

    My first mistake was to take MSDN literally:
    The const_cast operator can be used to remove the const, volatile, and __unaligned attribute(s) from a class.
    Second mistake was when I used this to test it out:
    Code:
        const int N = 5;
        const_cast<int>(N)++;
    How do you spell "assume" again?

    gg

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured