C++ 使用分隔符逐行读取文件并将数据存储到变量中

C++ Reading a file line by line with delimiter and store data into variable

本文关键字:数据 存储 变量 文件 分隔符 逐行 读取 C++      更新时间:2023-10-16

我对C++很陌生,我有一个带有数据的txt文件,看起来像这样:

测试:123:锁定

QWERTY:4321:解锁

ASDF:12:锁定

我是否可以使用 ":" 作为分隔符将数据逐行读取到变量/数组中?

我尝试做这样的事情:

while(!myfile.eof()) {       
    for (int i = 0; i < 3; i++) {
        getline(myfile,UserN[i],':'); 
    }
}

我想要实现的是将第一行的数据存储到UserN[0]UserN[1]UserN[2]中。当它开始读取第二行时,第二行的数据将替换 UserN[0]UserN[1]UserN[2] 中的值。提前感谢!

首先阅读该行,然后用std::stringstream标记它:

#include <sstream>
...
std::string line;
while(std::getline(myfile, line)) {       // cache the line
  std::istringstream tokenizer(line);
  std::getline(tokenizer, UserN[0], ':'); // then get the tokens from it
  std::getline(tokenizer, UserN[1], ':');
  std::getline(tokenizer, UserN[2]);      // last token: get the remainder
                                          // of the line.
  if(tokenizer) {
    // success!
  } else {
    // There were fewer than two colons in the line
  }
}

从本质上讲,std::istringstream将字符串包装在流接口中 - 生成的流的行为(大致)类似于具有与构建它的字符串相同的内容的文件。然后可以使用>>getline或任何其他可以在文件或std::cin或其他输入流上使用的东西,在这里我们使用它来将字符串分解到您需要的令牌中。

你可以简单地做到这一点

ifstream myfile( "aFile.txt" );
// .. check whether the file is open: if( !myfile.is_oppen() ) error
for( string userN[3]
    ; getline( getline( getline( myfile >> ws, userN[0], ':' ), userN[1], ':' ), userN[2] ); )
{
    // userN[0..2] is read correctly
}

或者以更优雅的方式,也许更适合您的要求。我假设第二个文本总是一个数字,第三个文本是"锁定"或"解锁"或其他类似枚举的东西。

enum class LockState 
{ 
    lock, unlock 
};
// --   reading a LockState
//      please consider, that behind the text must follow a white space character (Space, LF, ..)
std::istream& operator>>(std::istream& in, LockState& s)
{
    std::string word;
    if( in >> word )
    {
        if( word == "lock" )
            s = LockState::lock;
        else if( word == "unlock" )
            s = LockState::unlock;
        else
            in.setstate( std::ios_base::failbit );
    }
    return in;
}
struct Entry    // change the name 'Entry' of the struct suitable for Your requirements
{
    std::string someText;
    int aNr;
    LockState lockState;
};
// --   function to read an 'Entry'-object
std::istream& operator>>(std::istream& in, Entry& e)
{
    char colon;
    if( getline( in >> std::ws, e.someText, ':' ) >> e.aNr >> colon
        && colon != ':' )
        in.setstate( std::ios_base::failbit );
    else
        in >> e.lockState;
    return in;
}

以及稍后在您的主程序中

ifstream myfile( "aFile.txt" );
// .. check whether the file is open: if( !myfile.is_oppen() ) error
for( Entry e; myfile >> e; )
{
    // use here the Entry-object 'e'
}
if( myfile.eof() )
    cout << "Ok - You read the file till the end" << endl;

避免这里的麻烦,并使用 Boost 中的拆分函数:

#include <fstream>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
// ...
// Read file and throw exception on error.
std::ifstream infile;
infile.open(file_name);
std::string line;
while (std::getline(infile, line))
{
    // Strip of the comments.
    std::vector<std::string> strings;
    boost::split(strings, line, boost::is_any_of(":"));
    // You have now a vector of strings, which you can process...
}