2017-05-19 3 views
0

私は、ファイルを開き、各行を読み込み、最後の名前、名前:3つのテストのスコアを区切ることができるプログラムを作成しています。読み込まれるファイルの形式はMark Titan:80 80 85です。私はTITAN、Mark:80 80 85を出力すると仮定しています。私たちは文字列を使用していますが、これまで私の教師コードを使用しています。 1から100までの順でテストスコアを表示します(最初は1で始まるので100が最初に来ますが、その後は修正できます)。アルファベット順に名前が表示されます。私は行のsubstrを作成する助けを必要とし、ちょうどフルネームの文字列を作成し、それを最初と最後に分割して、それを正しくソートします。私は.findを使いこなしていますが、このベクトルをより小さなベクトルに分割する方法がわかりません。助けてくれてありがとう。C++の文字列ヘルプ、文字列を打つ

#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;} 
+0

[分割の可能性のある重複した文字列C++?](http://stackoverflow.com/questions/236129/split-a-string-in-c) –

答えて

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, "{}, "); 
0

私は、文字列操作のための方法の束を持って、このユーティリティクラスを持っています。区切り文字で文字列を分割するクラス関数を示します。このクラスはプライベートコンストラクタを持ち、このクラスのインスタンスを作成することはできません。すべてのメソッドは静的メソッドです。

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; 
}