使用 ifstream 提取运算符C++>>从文件中读取格式化数据
Using C++ ifstream extraction operator>> to read formatted data from a file
作为我的学习,我试图使用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 */ }
-
ifstream
默认有ios_base::in
。你不需要指定它。 -
operator>>
可以作为操作符直接调用:in >> a
。 - 读取字符串是相同的:
in >> s
,但警告是它是空白分隔的,所以它将自己读取"just",没有"dummy"。 - 如果你想读取完整行,使用
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之类的工具编写解析器。
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 如何将内容数组写入文本文件?
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到