2016-01-06 72 views
0

我有一個問題,關於一些代碼來處理我正在閱讀的文件中的一些名稱或數字。因此,文件中的文字是這樣的:如何以特定的方式讀取和處理文件中的文本?

Imp;1;down;67 
Comp;3;up;4 
Imp;42;right;87 

正如你可以看到,有3行文字和字符分隔的數字「;」 。我想一次讀取每一行,並將整行字符串拆分成單詞和數字,然後處理這些信息(將用於用數據創建一個新對象)。然後轉到下一行,依此類推,直到EOF。

所以,我想讀取文本的第一行,將其分割成一串由字和數字組成的字符串,然後創建一個類的對象。例如,對於第一行,創建類Imp的對象,如Imp objImp(Imp, 1, down, 67)

在Java中,我使用information = line.split(";")'(其中行是一行文本)做了同樣的事情,然後使用information[0],information[1]來訪問字符串數組的成員並創建對象。我試圖在這裏做同樣的事

+2

它看起來像你的代碼讀取一行,打印它,並重復,直到什麼都不剩閱讀。這符合你對我想的事物的描述......那麼問題是什麼? _it不會在第一行後停止,所以我可以插入我需要的代碼 - 恩,恩?你沒有很好地描述你的問題,你似乎沒有添加任何代碼來處理該行('output'),而不是打印它。 – mah

+1

您正在'getline'中使用常量'256'來引發崩潰。你應該在這裏使用'sizeof(output)'。 – Logicrat

+0

@mah我沒有解釋我想要做的事情,讓我再試一次。所以,我想要讀取文本的第一行,將它分解爲由行中的單詞和數字組成的字符串數組,然後從它們中創建一個類的對象。例如,對於第一行,創建類Imp這樣的對象,如'Imp objImp(Imp,1,down,67)'。我Java使用'information = line.split(「;」)'(其中line是一行文本)做了同樣的事情,然後使用'information [0]','information [1]'來訪問成員字符串數組並創建對象。我正試圖在這裏做同樣的事情 – Alex

回答

3

不要使用char陣列緩衝區,和don't use std::istream::eof。據說,讓我們繼續解決問題。

std::getline類似於std::istream::getline,除了它使用std::string而不是char陣列。

在這兩個參數delim意味着一個分隔字符,但在某種程度上,它是字符,當遇到,std::getline停止閱讀(不保存並丟棄它)。這並不意味着一個分隔符,它會在整個生產線上爲每個;奇蹟般地分割輸入。

因此,你必須這樣做:

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

... 

std::ifstream myFile("D:\\stuff.txt"); // one statement 

if (myFile.is_open()) { 
    std::string line; 

    while (std::getline(myFile, line)) { // line by line reading 
     std::istringstream line_stream(line); 
     std::string output; 

     while (std::getline(line_stream, output, ';')) // line parsing 
      std::cout << output << std::endl; 
    } 
} 

我們從構建一個linestd::istringstream,所以我們可以std::getline再次解析它。

+1

[Live Demo](http://coliru.stacked-crooked。com/a/d092549929aa1898)您的代碼在行動中。 – AndyG

+0

謝謝,代碼確實工作正常,但我第一次不正確地提出了我的問題。與此同時,我編輯了最初的問題,請參閱最後一部分,瞭解我正在嘗試在現在編輯的初始問題中實現的內容,以防您有任何想法 – Alex

+0

@Alex不是打印'output',而是將它推入'std: :vector '重新創建外部循環的每個迭代,然後檢查它的大小,使用[這些函數](http://en.cppreference.com/w/cpp/string/basic_string/stol),如果你需要將'std :: string'轉換爲整數。 – LogicStuff

1

另外一個(略有不同)替代:

/* 
* Sample output: 
* line:Imp;1;down;67 
*  "Imp", "1", "down", "67" 
* line:Comp;3;up;4 
*  "Comp", "3", "up", "4" 
* line:Imp;42;right;87 
*  "Imp", "42", "right", "87" 
* line:Imp;42;right;87 
*  "Imp", "42", "right", "87" 
*/ 
#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
#include <vector> 

using namespace std; 

void split(const std::string &s, char delim, std::vector<string> &fields) 
{ 
    fields.clear(); 
    std::stringstream ss(s); 
    std::string item; 
    while (std::getline(ss, item, delim)) { 
     fields.push_back(item); 
    } 
} 

void print (std::vector<string> &fields) 
{ 
    cout << " "; 
    for (size_t i = 0; i < fields.size() - 1; i++) 
    cout << "\"" << fields[i] << "\", "; 
    cout << "\"" << fields[fields.size()-1] << "\"" << endl; 
} 

int main() 
{ 
    std::ifstream fp("tmp.txt"); 
    std::string line; 
    while (!fp.eof()) { 
    fp >> line; 
    cout << "line:" << line << endl; 
    std::vector<std::string> fields; 
    split(line, ';', fields); 
    print(fields); 
    } 
    fp.close(); 
    return 0; 
} 
相關問題