2016-01-06 79 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; 
} 
相关问题