使用 ifstream 提取运算符C++>>从文件中读取格式化数据

Using C++ ifstream extraction operator>> to read formatted data from a file

本文关键字:gt 文件 读取 格式化数据 ifstream C++ 提取 使用 运算符      更新时间:2023-10-16

作为我的学习,我试图使用c++ ifstream及其操作符>>从文本文件中读取数据,使用下面的代码。outdummy.txt文本文件包含以下内容:

just dummy
Hello ofstream
555

我的问题是如何将文件中存在的字符数据读取为字符数组或字符串。如何使用ifstream::操作符>>在下面的代码中做到这一点。

#include <iostream>
#include <fstream>
int main()
{
    int a;
    string s;
    char buf[100];
    ifstream in("outdummy.txt",ios_base::in);

    in.operator>>(a); //How to read integer? How to read the string data.??
    cout << a;
    in.close();
    getchar();
    return 0;
}

如果希望使用格式化的输入,则必须事先知道期望得到什么数据,并将其读入相应数据类型的变量中。例如,如果您知道数字总是第五个令牌,如在您的示例中,您可以这样做:

std::string s1, s2, s3, s4;
int n;
std::ifstream in("outdummy.txt");
if (in >> s1 >> s2 >> s3 >> s4 >> n)
{
  std::cout << "We read the number " << n << std::endl;
}

另一方面,如果你知道这个数字总是在第三行,它本身:

std::string line;
std::getline(in, line);  // have line 1
std::getline(in, line);  // have line 2
std::getline(in, line);  // have line 3
std::istringstream iss(line);
if (iss >> n)
{
  std::cout << "We read the number " << n << std::endl;
}

如您所见,要将令牌作为字符串读取,只需将其流式传输到std::string。重要的是要记住,格式化的输入操作符逐个标记地工作,并且标记由空格(空格、制表符、换行符)分隔。通常要做出的基本选择是,是完全以令牌形式处理文件(第一个版本),还是逐行处理文件(第二个版本)。对于逐行处理,首先使用getline将一行读入字符串,然后使用字符串流对字符串进行标记。


关于验证的一句话:您无法知道格式化的提取是否会真正成功,因为这取决于输入数据。因此,您应该始终检查输入操作是否成功,如果不成功则终止解析,因为在失败的情况下,您的变量将不包含正确的数据,但您以后无法知道这一点。所以总是这样说:

if (in >> v) { /* ... */ }            // v is some suitable variable
else { /* could not read into v */ }
if (std::getline(in, line)) { /* process line */ }
else { /* error, no line! */ }

后一种结构通常用于while循环,逐行读取整个文件:

while (std::getline(in, line)) { /* process line */ }
  1. ifstream默认有ios_base::in。你不需要指定它。
  2. operator>>可以作为操作符直接调用:in >> a
  3. 读取字符串是相同的:in >> s,但警告是它是空白分隔的,所以它将自己读取"just",没有"dummy"。
  4. 如果你想读取完整行,使用std::getline(in, s)

既然你已经选择使用C-string,你可以使用你的ifstream对象的getline方法(不是std::getline(),它与std::string s一起工作),它将允许你指定C-string和缓冲区的最大大小。

根据您已有的内容,并为第二行添加额外的缓冲区:

char buf[100];
char buf2[100];
in.getline(buf,sizeof(buf));
in.getline(buf2,sizeof(buf2));
in >> a;

然而,正如其他海报所建议的,尝试使用std::string和它的方法,它会让你的生活更容易。

您可以读取文件内容并使用有限状态机进行解析。

的例子:

void Parse(const char* buffer, size_t length);
size_t GetBufferSize();
size_t bufferSize = GetBufferSize();
char* buffer = new char[bufferSize];
std::ifstream in("input.txt");
while(in.getline(buffer, bufferSize)) {
    Parse(buffer, in.gcount());
}

或者,您可以使用Flex之类的工具编写解析器。