2014-11-23 81 views
3

這是另一個我似乎無法找到答案的問題,因爲我可以找到的每個示例都使用向量,而我的老師不會讓我們使用這個類的向量。stringstream與多個分隔符

我需要使用(任意數量的),同時在一本書一個字的純文本格式閱讀空格
' '和(任意數量的)非字母字符是分隔符;所以任何數量的空格或標點都需要分開單詞。下面是我如何做它時,它只是使用空格作爲分隔符必要的:

while(getline(inFile, line)) { 
    istringstream iss(line); 

    while (iss >> word) { 
     table1.addItem(word); 
    } 
} 

編輯:閱讀文本的一個例子,我需要如何分開吧。

「如果他們知道你;;希望吧,entertainment.would有」

這裏的第一行會如何需要分開:

如果

他們

希望

娛樂

的文本將包含至少是所有標準的標點符號,而且這樣的事情橢圓...雙破折號--

和往常一樣,在此先感謝。

編輯:

因此,使用第二字符串流會是這個樣子?

while(getline(inFile, line)) { 
    istringstream iss(line); 

    while (iss >> word) { 
     istringstream iss2(word); 

     while(iss2 >> letter) { 
      if(!isalpha(letter)) 
       // do something? 
     } 
     // do something else? 
     table1.addItem(word); 
    } 
} 
+0

使用流提取一個詞,忽略空白(默認值)。然後放入一個新的字符串流,並使用'std :: isalnum'來一次提取1個字符來測試字符是否應該被存儲。或者在字符串上使用'remove_if'。 – 2014-11-23 23:13:48

+0

@Neil Kirk Original Edited。一旦我確定它是否是信件,我將如何丟棄/重新存儲每個角色? – user3776749 2014-11-23 23:27:15

+0

如果它不是alnum,請不要將它添加到輸出字符串中。字母必須是字符 – 2014-11-23 23:52:36

回答

2

我沒有測試過這一點,因爲我沒有在我面前一G ++編譯器現在,但它應該(從微量碳一旁++的語法錯誤)工作

while (getline(inFile, line)) 
{ 
    istringstream iss(line); 

    while (iss >> word) 
    { 
     // check that word has only alpha-numeric characters 
     word.erase(std::remove_if(word.begin(), word.end(), 
            [](char& c){return !isalnum(c);}), 
        word.end()); 
     if (word != "") 
      table1.addItem(word); 
    } 
} 
+0

這似乎工作,但我還沒有做過壓力測試。我認爲這將是一個更安全的賭注,因爲它只需要。我確實有一個問題,你能解釋一下這裏發生了什麼: '[](char&c){return!isalnum(c);}' 我有一個體面的想法,我認識到各個部分,但我沒有上下文來完全放置它正在做的事情。 – user3776749 2014-11-24 00:00:06

+0

@ user3776749實際上它並不真正起作用,就好像字符串就像「test。; works」一樣,然後片段將它從中刪除,然後用一個單詞將「testworks」吐出來。上面的函數稱爲lambda函數(C++ 11),只要字符不是字母數字就返回true。我想最好的選擇是編寫自己的標記器(或使用Boost),儘管編寫自己的標記不應該太過痛苦。爲了好玩,我給自己寫了一個標記器,它非常簡單,請參閱:https://github.com/vsoftco/tokenizer/blob/master/src/token.cpp它爲您提供了一個總體思路。 – vsoftco 2014-11-24 00:03:18

+0

@ user3776749所以你應該做的是讀取'word',開始解析並找到不是字母數字的第一個字符,添加單詞,然後找到字母數字的第一個字符,並繼續重複直到' word'。 – vsoftco 2014-11-24 00:08:51

1

如果您可以自由使用Boost,你可以做到以下幾點:

$ cat kk.txt 
If they had known;; you ... wished it, the entertainment.would have 

如果需要,您可以自定義的tokenizer的行爲,而是默認的應該是足夠的。

#include <iostream> 
#include <fstream> 
#include <string> 

#include <boost/tokenizer.hpp> 

int main() 
{ 
    std::ifstream is("./kk.txt"); 
    std::string line; 

    while (std::getline(is, line)) { 
    boost::tokenizer<> tokens(line); 

    for (const auto& word : tokens) 
     std::cout << word << '\n'; 
    } 

    return 0; 
} 

最後

$ ./a.out 
If 
they 
had 
known 
you 
wished 
it 
the 
entertainment 
would 
have 
+0

這是一個有趣的解決方案,我將其保存以供將來使用,但爲了確保我的老師不會大驚小怪,我想堅持只需要非常基本功能庫的解決方案。 – user3776749 2014-11-24 00:05:26