c ++读取多行,不同的分隔符

时间:2014-03-18 19:16:46

标签: c++ stringstream

输入文件的结构如下:

First Last,33,Male,city
score1,15/30
score2, 20/20

First Last,43,Female,city
score1,20/20
score2,18/20

具有未知数量的记录,每个记录用空行分隔。每条记录都成为一个存储在动态数组对象中的对象(这本身就令人困惑)。

我可以将第一行放入变量中,但其余的行在以太中丢失。虽然它产生了适当数量的记录(在这种情况下,它将是2),但每条记录都填充了第一行的数据而没有得分。

我对如何正确阅读它没有任何想法,但仍然不知道如何处理每条记录之间的空白行。这是以前的作业,我无法从任何人那里得到直接的答案,并且很想知道,因为从文件中读书似乎风靡一时......

这就是我所拥有的:

std::ifstream read_data(data_file);
std::string line;

while(std::getline(read_data, line))
{
     std::stringstream ss(line);
     char detectNewline;

     getline(ss, tempName, ',');
     getline(ss, tempAgeString, ',');
     tempAge = std::atoi(tempAgeString.c_str());
     getline(ss, tempGender, ',');
     getline(ss, tempCity, '\n';

           for(int i=0; i < 2; i++)  // I am not married to this idea, seems efficient
           {
                getline(ss, tempScore, ',');
                getline(ss, pointsEarnedHolder, '/');
                tempPointsEarned += std::atof(pointsEarnedHolder.c_str());
                getline(ss, totalPointsHolder, '\n');
                tempTotalPoints += std::atof(totalPointsHolder.c_str());
           }

           // variable manipulation

           ClassName object(proper vars);
           previouslyDeclaredDynamicArrayObject(object);

           detectNewline = read_data.peek();
           if(detectNewline == '\n')
           {
              std::cin.ignore();
           }

} //while

感谢您的任何见解!

2 个答案:

答案 0 :(得分:0)

我将触及有效阅读信息的方式。

首先,您可以获取第一行并解析您拥有的信息。然后,您将解析分数中提供的信息,直到getline出现空白行。然后,一旦发生这种情况,您将把对象添加到数组中,并获取下一个对象的起始信息,然后重复该过程。

代码看起来与此类似(漂亮的伪y):

std::getline(read_data, line);
while( !read_data.eof() ) {
   std::stringstream ss(line);

   getline(ss, tempName, ',');
   getline(ss, tempAgeString, ',');
   tempAge = std::atoi(tempAgeString.c_str());
   getline(ss, tempGender, ',');
   getline(ss, tempCity, '\n';
   std::getline( read_data, line )
   while( line != "\n" ) {
        getline(ss, tempScore, ',');
        getline(ss, pointsEarnedHolder, '/');
        tempPointsEarned += std::atof(pointsEarnedHolder.c_str());
        getline(ss, totalPointsHolder, '\n');
        tempTotalPoints += std::atof(totalPointsHolder.c_str());
        std::getline( read_data, line )
   }

         // variable manipulation

         ClassName object(proper vars);
         previouslyDeclaredDynamicArrayObject(object);
         std::getline(read_data, line);

 } //while

这是假设您正在从行中正确提取信息。

答案 1 :(得分:0)

分隔这些字符的一种更简单的方法是通过流语言环境的std::ctype<>方面将它们分类为空白。然后你可以简单地使用提取器operator>>()而不是解析未格式化的函数。

以下是如何设置构面的示例:

struct ctype : std::ctype<char>
{
    static mask* make_table()
    {
        const mask* table = classic_table();
        static std::vector<mask> v(table, table + table_size);
        v[' '] |= space;
        v[','] |= space;
        v['/'] |= space;
        return &v[0];
    }

    ctype() : std::ctype<char>(make_table()) { }
};

然后,您可以制作一个便利功能,将其安装到流的区域设置中:

std::istream& custom_ctype(std::istream& is)
{
    is.imbue(std::locale(is.getloc(), new ctype));
    return *is;
}

// ...
file >> custom_ctype;

之后,将文件中的字符提取到变量中变得很简单。只要想想你想要忽略的角色,就像它们是空格角色或换行符一样,因为这正是我们在这里所做的。