Breaking a single string into multiple strings C++?

后端 未结 3 1075
太阳男子
太阳男子 2020-12-21 21:18

I need to input 3 full names separated by commas

Full Name 1: John, Smith, Flynn
Full Name 2: Walter, Kennedy, Roberts
Full Name 3: Sam, Bass, Clinton

相关标签:
3条回答
  • 2020-12-21 21:48

    I'd probably do something like this:

    Edit: after some thought, I've decided the duplication really did bother me too much, so I've eliminated it. I'm not sure it's technically allowed (std::string isn't a POD) but it seems to work, and strikes me as nicer and more scalable.

    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <iterator>
    
    struct name { 
        std::string first, middle, last;
    };
    
    std::istream &operator>>(std::istream &is, name &n) { 
        char ch;
        is.ignore((unsigned)-1, ':');
        is.ignore(1);
    
        std::getline(is, n.first, ',');
        std::getline(is, n.middle, ',');
        std::getline(is, n.last);
        return is;
    }
    
    struct item { 
        size_t offset;
        char *caption;
    };
    
    void show(name const &n, item const &i) { 
        // as predicted, eliminating the duplication did lead to one gnarly line of code:
        std::string &name = *(std::string *)((char *)&n+i.offset);
        std::cout << i.caption << name << "\n";
    }
    
    int main() {     
        std::vector<name> names;
    
        std::string raw_data("Full Name 1: John, Smith, Flynn\nFull Name 2: Walter, Kennedy, Roberts\nFull Name 3: Sam, Bass, Clinton");
    
        std::istringstream infile(raw_data);
    
        std::copy(std::istream_iterator<name>(infile),
                  std::istream_iterator<name>(),
                  std::back_inserter(names));
    
        item items[] = { 
            {offsetof(name, first), "First Name: "},
            {offsetof(name, middle), "Middle Name: "},
            {offsetof(name, last), "Last name: "} 
        };
    
        for (int i=0; i<3; i++) {
            for (int j=0; j<3; j++)
                show(names[j], items[i]);
            std::cout << "\n";
        }
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-21 22:01

    I think here what you want to is a split method for string class, the method should like this:

    void SplitName(const string& fullName, const string& delims, vector<string>& names)
    {
        size_t i = 0;
        size_t j = 0;
        while (i < fullName.size())
        {
            i = fullName.find_first_not_of(delims, i);
            j = fullName.find_first_of(delims, i);
            if (i < fullName.size())
            {
                names.push_back(fullName.substr(i, j - i));
            }
            i = j;
        }
    }
    

    you can define the ":," as delims, then names[1] is First Name, names[2] is Middle Name, names[3] is Last Name.

    0 讨论(0)
  • 2020-12-21 22:11
    void DumpName(char*  pBuffer, char cDelimiter, int iCounter);
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        char full[3][100];
    
        cout << "Enter 3 Full Names <first, middle and last names separated by comma>:" << endl;
        for (int i=0; i<3; i++) {
             cout << "Full Name " << i+1 << ":" ;
            gets (full[i]);          
        }
    
        for(int i=0; i<3; i++)
        {
            cout << "First Name "<< i+1 << ":" ;
            DumpName(full[i], ',', 0);
        }
    
        for(int i=0; i<3; i++)
        {
            cout << "Middle Name "<< i+1 << ":" ;
            DumpName(full[i], ',', 1);
        }
    
        for(int i=0; i<3; i++)
        {
            cout << "Last Name "<< i+1 << ":" ;
            DumpName(full[i], ',', 2);
        }
    
        return 0;
    }
    
    void DumpName(char*  pBuffer, char cDelimiter, int iCounter)
    {
        int iFound = 0;
    
        char* pStart = pBuffer;
        char* pCurrent = pBuffer;
        while(*pCurrent != '\0')
        {
            if(*pCurrent == cDelimiter)
            {
                if(iFound == iCounter)
                {
                    *pCurrent = '\0';
                    cout << pStart << endl;
                    *pCurrent = cDelimiter;
                    return;
                }
    
                pStart = pCurrent;
                pStart ++;
                iFound ++;
            }
    
            pCurrent ++;
        }
    
        if((iCounter - iFound) == 0)
            cout << pStart << endl;
    }
    
    0 讨论(0)
提交回复
热议问题