Thread: convert a vector<string> into a string

  1. #1
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310

    convert a vector<string> into a string

    This is my vector:
    Code:
    vector<string> ext;
    exts.push_back(TEXT("png"));
    exts.push_back(TEXT("jpg"));
    exts.push_back(TEXT("gif"));
    exts.push_back(TEXT("bmp"));
    I wan to create the vector into a string to have like the OPENFILENAME::lpstrFilter, that would be something like:
    Code:
    string final = "All files supported\0*.png;*.jpg;*.gif;*.bmp\0\0";
    Right now I'm using something like this:
    Code:
    vector<string> ext;
    	stringstream str;
    	ext.push_back("png");
    	ext.push_back("jpg");
    	ext.push_back("bmp");
    	ext.push_back("gif");
    	size_t len = ext.size();
    	str << "All files supported\0";
    	for (size_t pos = 0; pos != len; pos++ )
        {
            str << "*." << ext[pos] << ";";
        }
    str << "\0\0";
    	// use str.str().c_str() as filter
    But doesn't work
    any ideas?
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Try using something other than \0 as a delimiter.

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I guess the null characters are not inserted because in a C-style string (string literal) they mean the end of string.

    You can use string concatenation, and take care with inserting null characters in the string (cannot be done as part of a string literal).

    Code:
    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    int main()
    {
        vector<string> ext;
        ext.push_back("png");
        ext.push_back("jpg");
        ext.push_back("bmp");
        ext.push_back("gif");
        size_t len = ext.size();
        string filter = "All files supported";
        filter += '\0';
        for (size_t pos = 0; pos != ext.size(); pos++ )
        {
            filter += "*." + ext[pos] + (pos + 1 < len ? ";" : "");
        }
        filter += string(2, '\0'); //two more null characters
        std::cout << "'" << filter << "'";
    }
    Try using something other than \0 as a delimiter.
    That's how the API likes it.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I don't know what OP expected to happen, but when I ran his code, it did exactly what yours would do anon. That is, str.str().c_string() is like a concatenated string. So my only guess was that he saw something he didn't expect, which would only require using a different delimiter to see the effect.

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I hardly believe it would be the same. In my code the resulting string is 45 characters, OP's resulting string is 43 (no null characters, one extra semicolon).

    Those two have the exact same effect:
    Code:
    str << "\0\0";
    str << "";
    Neither one inserts any characters in the stream.

    If you use a different character, the problem will naturally go away, except your string will contain wrong delimiters. (You could replace those later.)
    Last edited by anon; 02-26-2011 at 03:55 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The interaction between the std::string type and strings that contain a zero byte is a bit fiddly, if you rely on them being more than 1. I'd actually use a vector as an intermediary.
    Code:
        // untested code follows - written to show idea, not guaranteed correct
    
        char *tempfilter = "All files supported";
        
        std::vector<char> filter(0);
        filter.insert(filter.end(), tempfilter, tempfilter + strlen(tempfilter));   //  this takes the first '\0' for the ride
        for (std::vector<std::string>::const_iterator i = ext.begin(), end = ext.end(); i != end; ++i)
        {
               if (i->length() > 0)
               {
                      std::string temp = "*.";
                      temp += *i;
                      if (i + 1 != end) temp += ';'
    
                      filter.insert(filter.end(), temp.begin(), temp.end());
               }
        }
        filter.insert(filter.end(), '\0');
        filter.insert(filter.end(), '\0');
     
        std::string filter_to_use(filter.begin(), filter.end());
    Note that printing the filter out (std::cout << filter) will only print to the first null character - by convention.
    Last edited by grumpy; 02-26-2011 at 04:07 PM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I believe you missed a curly brace in there. Also, the end of the string should be double null terminated.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310
    Thanks, guys...I read about map and googled around and I came with this:
    Code:
    ustring CWnd::MakeFilter()
    {
        /* mapped the file extensions that we want to use */
        m_Filtro["Archivos PNG"] = "png";
    	m_Filtro["Archivos JPEG"] = "jpg";
    	m_Filtro["Archivos GIF"] = "gif";
    	m_Filtro["Archivos BMP"] = "bmp";
    	/* begin filter maker */
        stringstream str;
        str << "Todos los soportados|";
        MapFiltro::iterator it;
        size_t len = m_Filtro.size();
        size_t pos = 0;
        for (it = m_Filtro.begin(); it != m_Filtro.end(); it++,pos++)
        {
            str << "*." << it->second << (pos < len-1 ? ";" : "");
        }
        str << "|";
        for (it = m_Filtro.begin(); it != m_Filtro.end(); it++)
        {
            str << it->first << "|*." << it->second << "|";
        }
        str << "|";
        ustring final = str.str();
        replace(final.begin(),final.end(),'|','\0');
        return final;
    }
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 03-03-2006, 02:11 AM
  2. can anyone see anything wrong with this code
    By occ0708 in forum C++ Programming
    Replies: 6
    Last Post: 12-07-2004, 12:47 PM
  3. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM
  4. ........ed off at functions
    By Klinerr1 in forum C++ Programming
    Replies: 8
    Last Post: 07-29-2002, 09:37 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM