CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Correct way to truncate a std::string

    A buffer gets filled with the path to a file:-

    Code:
    char tmpBuf[MAX_PATH+3];
    sprintf(tmpBuf, "\"%s\"", strFileToImport.c_str());
    Note that at this stage, the path is surrounded by double quote marks.

    Later, I need to assign that path (without the quote marks) to a std::string

    Code:
    std::string strPathToNewProject = &tmpBuf[1];
    // Remove the trailing double quote marks....
    strPathToNewProject[strPathToNewProject.length()-1] = 0;
    So far, this appears to go okay, but later I need to pass that string to Glib::filename_to_utf8:-

    Code:
    Glib::ustring ustr = Glib::filename_to_utf8(strPathToNewProject);
    However, Glib::filename_to_utf8() throws an exception. I think it must have something to do with the length of the string because I don't get the exception if I don't strip off that trailing double-quote mark. How should I truncate the std::string safely?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Correct way to truncate a std::string

    There is a resize() function you can use. Additionally, you can simply construct it smaller to begin with:

    Code:
    std::string strPathToNewProject(tmpBuf + 1, strlen(tmpBuf)-2);

  3. #3
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Correct way to truncate a std::string

    resize() worked fine Lindley, thanks. I'll have to remember that in future. It was a complete surprise when my original approach caused this problem.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Correct way to truncate a std::string

    Fundamentally, std::strings do not rely on NULL-termination to denote the end of the string. It is valid for a std::string to contain a 0 byte. However, apparently it is *not* valid to hand such a std::string into that Glib function, which is interesting. Is that limitation documented?

  5. #5
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Correct way to truncate a std::string

    I'll see if I can find out.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Correct way to truncate a std::string

    Quote Originally Posted by John E View Post
    So far, this appears to go okay, but later I need to pass that string to Glib::filename_to_utf8:-
    What is the prototype of this function? That is one thing you didn't post.

    If that function's parameter is not std::string, you can't give it a std::string.
    However, Glib::filename_to_utf8() throws an exception. I think it must have something to do with the length of the string because I don't get the exception if I don't strip off that trailing double-quote mark. How should I truncate the std::string safely?
    Until you show how filename_to_utf8 is declared, no one can say really what is going on. There are std::string classes that have the buffer as the first member, and passing that to a function that takes char* may seem to work, when it's just pure luck that it did work.

    Also, what was the exception that was thrown? Was it a glib exception? Is that function guaranteed to throw an exception on error? If so, you need to enclose your code in a try/catch block and get the real reason why the exception was thrown by inspecting the what() member function of the exception object (if the exception is derived from std::exception).

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Mar 2008
    Location
    Turin / Italy
    Posts
    178

    Re: Correct way to truncate a std::string

    Another option if you have a C++0x compiler is using string::pop_back
    http://www.cppreference.com/wiki/str...tring/pop_back

  8. #8
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Correct way to truncate a std::string

    Quote Originally Posted by SkyNetTo
    Another option if you have a C++0x compiler is using string:op_back
    I believe pop_back is a member function of std::basic_string in the current standard library.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  9. #9
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Correct way to truncate a std::string

    Quote Originally Posted by Paul McKenzie View Post
    Until you show how filename_to_utf8 is declared, no one can say really what is going on.

    [...]

    Also, what was the exception that was thrown? Was it a glib exception?
    Paul - yes, it's a Glib exception. I stepped through the code this morning and it does make sense. Glib::filename_to_utf8() is a wrapper around g_filename_to_utf8() which actually detects the error. You can see here where (and why) the exception gets thrown:-

    Code:
    namespace Glib
    {
    
    Glib::ustring filename_to_utf8(const std::string& opsys_string)
    {
      gsize bytes_written = 0;
      GError* error = 0;
    
      char *const buf = g_filename_to_utf8(
          opsys_string.data(), opsys_string.size(), 0, &bytes_written, &error);
    
      if(error)
        Error::throw_exception(error);
    
      const ScopedPtr<char> scoped_buf (buf);
      return Glib::ustring(scoped_buf.get(), scoped_buf.get() + bytes_written);
    }
    
    }
    and here's the source code for g_filename_to_utf8()

    Code:
    gchar*
    g_filename_to_utf8 (const gchar *opsysstring, 
    		    gssize       len,           
    		    gsize       *bytes_read,   
    		    gsize       *bytes_written,
    		    GError     **error)
    {
      const gchar *charset;
    
      if (get_filename_charset (&charset))
        return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
      else
        return g_convert (opsysstring, len, 
    		      "UTF-8", charset, bytes_read, bytes_written, error);
    }
    The red line detects the error which equates to:- "invalid byte sequence in conversion input". So it looks like the NULL terminator that I added to my std::string has been detected as an invalid byte for conversion. Seems sensible enough, given what Lindley said earlier.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Correct way to truncate a std::string

    Quote Originally Posted by John E View Post
    Paul - yes, it's a Glib exception. I stepped through the code this morning and it does make sense. Glib::filename_to_utf8() is a wrapper around g_filename_to_utf8() which actually detects the error. You can see here where (and why) the exception gets thrown:-
    Ok. However you still need to wrap your code using a try/catch, if you haven't done so already.
    The red line detects the error which equates to:- "invalid byte sequence in conversion input". So it looks like the NULL terminator that I added to my std::string has been detected as an invalid byte for conversion.
    To be more exact, the thing that trips you up is the function's use of string::size() to determine the length of the string data, and not strlen().

    That extra NULL byte you added changes everything when it comes to size(), but wouldn't have had any effect if the routine used strlen().

    Regards,

    Paul McKenzie

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