【问题标题】:C++ string help, Spitting a stringC++ 字符串帮助,吐出一个字符串
【发布时间】:2017-10-18 23:44:20
【问题描述】:

我正在编写一个程序,它应该能够打开一个文件,读取每一行并分隔一个 LAST NAME,First name:3 个测试分数。正在读取的文件格式是 Mark Titan:80 80 85。我想输出 TITAN,Mark:80 80 85。我们正在使用字符串,到目前为止,使用我的老师代码我已经将文件完全分开。它将按 1-100 的顺序显示测试分数(100 排在第一位,因为它以 1 开头,但我可以在之后修复它),然后按字母顺序显示名称。我需要帮助创建该行的子字符串,创建一个仅包含全名的字符串并将其拆分为第一个和最后一个,然后正确排序。我一直在搞乱 .find 但我不确定如何将此向量拆分为更小的向量。请帮忙,谢谢。

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <sstream>

    using namespace std;
    void openFile(ifstream &in);
    void processFile(ifstream &in, vector<string> &list);
    void display(const vector<string> &list);
    void sort(vector<string> &list);

    int main(int argc, char *argv[])
    {
        ifstream in;
        string line;
        vector<string> words;
        openFile(in);
        processFile(in, words);
        display(words);
        return 0;
    }


    void openFile(ifstream &in)
    {
        string fileName;
        bool again;
        do
        {
            again = false;
            cout<<"What is the name of the file to you wish to sort? (.txt will be added if no extension is included): ";
            cin>>fileName;
            if(fileName.find('.') >= fileName.size() )
                fileName +=  ".txt";
            in.open(fileName.c_str());
            if(in.fail())
            {
                in.close();
                in.clear();
                again = true;
                cout<<"That file does not exist! Please re-enter"<<endl;
            }
        }while(again);
    }

    void processFile(ifstream &in, vector<string> &list)
    {
        string line, word;
        int s1,s2,s3;
        stringstream ss;
        while(getline(in, line, ':'))
        {
            ss<<line.substr(line.find(' ') + 1);
            while(ss>>word)
                list.push_back(word);
            ss.clear();
        }
        sort(list);
    }

    void sort(vector<string> &list)
    {
        for(unsigned int i =  0; i < list.size(); ++i)
            for(unsigned int j = 0; j < list.size(); ++j)
                if(list[i] < list[j])
                {
                    string temp = list[i];
                    list[i] = list[j];
                    list[j] = temp;
                }
    }

    void display(const vector<string> &list)
    {
        cout<<"The file read had "<<list.size()<<" words in it"
            <<endl<<"In sorted order, they are:"<<endl;
        for(unsigned int i = 0; i < list.size();++i)
            cout<<list[i]<<endl;}

【问题讨论】:

标签: c++ string c++11 vector split


【解决方案1】:

我有一个实用程序类,它有一堆字符串操作方法。我将展示用分隔符分割字符串的类函数。此类具有私有构造函数,因此您无法创建此类的实例。所有方法都是静态方法。

Utility.h

#ifndef UTILITY_H
#define UTILITY_h

// Library Includes Here: vector, string etc.

class Utility {
public:
    static std::vector<std::string> splitString( const std::string& strStringToSplit,
                                                 const std::string& strDelimiter,
                                                 const bool keepEmpty = true );

private:
    Utility();
};

Utility.cpp

std::vector<std::string> Utility::splitString( const std::string& strStringToSplit, 
                                               const std::string& strDelimiter, 
                                               const bool keepEmpty ) {
    std::vector<std::string> vResult;
    if ( strDelimiter.empty() ) {
        vResult.push_back( strStringToSplit );
        return vResult;
    }

    std::string::const_iterator itSubStrStart = strStringToSplit.begin(), itSubStrEnd;
    while ( true ) {
        itSubStrEnd = search( itSubStrStart, strStringToSplit.end(), strDelimiter.begin(), strDelimiter.end() );
        std::string strTemp( itSubStrStart, itSubStrEnd );
        if ( keepEmpty || !strTemp.empty() ) {
            vResult.push_back( strTemp );
        }

        if ( itSubStrEnd == strStringToSplit.end() ) {
            break;
        }

        itSubStrStart = itSubStrEnd + strDelimiter.size();
    }

    return vResult;    
} 

Main.cpp -- 用法

#include <string>
#include <vector>
#include "Utility.h"

int main() {
    std::string myString( "Hello World How Are You Today" );

    std::vector<std::string> vStrings = Utility::splitString( myString, " " );

    // Check Vector Of Strings
    for ( unsigned n = 0; n < vStrings.size(); ++n ) {
        std::cout << vStrings[n] << " ";
    }
    std::cout << std::endl;

    // The Delimiter is also not restricted to just a single character
    std::string myString2( "Hello, World, How, Are, You, Today" );

    // Clear Out Vector
    vStrings.clear();

    vStrings = Utility::splitString( myString2, ", " ); // Delimiter = Comma & Space

    // Test Vector Again
    for ( unsigned n = 0; n < vStrings.size(); ++n ) {
        std::cout << vStrings[n] << " ";
    }
    std::cout << std::endl;

    return 0;
}

【讨论】:

    【解决方案2】:

    您可以对行进行两次标记。首先,在冒号上拆分,然后在空格上拆分第一个标记。此外,您的老师会向您扔空的和格式错误的行。例如缺少冒号或缺少姓名(或缺少名字/姓氏)。通过计算拆分字符串或子字符串时返回的标记来处理这些错误。

    void Tokenize(const std::string& theSourceString, std::vector<std::string>& theTokens, const std::string& theDelimiter)
    {
        // If no delimiter is passed, tokenize on all white space.
        if (theDelimiter.empty())
        {
            std::string aBuffer; // Have a buffer string
            std::stringstream ss(theSourceString); // Insert the string into a stream
    
            while (ss >> aBuffer)
            {
                theTokens.push_back(aBuffer);
            }
            return; //?
        }
    
        // Skip delimiters at beginning.
        std::string::size_type aLastPosition = theSourceString.find_first_not_of(theDelimiter, 0);
    
        // Find first "non-delimiter".
        std::string::size_type aPosition = theSourceString.find_first_of(theDelimiter, aLastPosition);
    
        while (aPosition != std::string::npos || aLastPosition != std::string::npos)
        {
            // Found a token, add it to the vector.
            theTokens.push_back(theSourceString.substr(aLastPosition, aPosition - aLastPosition));
    
            // Skip delimiters.  Note the "not_of"
            aLastPosition = theSourceString.find_first_not_of(theDelimiter, aPosition);
    
            // Find next "non-delimiter"
            aPosition = theSourceString.find_first_of(theDelimiter, aLastPosition);
        }
    }
    

    使用示例:

    std::vector<std::string> tokens;
    Tokenize("{ 1, 2, 3, 4, 5 }", tokens, "{}, " );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 2019-01-10
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      相关资源
      最近更新 更多