使用 C++ ifstream 提取运算符>>从文件中读取格式化数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7443787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using C++ ifstream extraction operator>> to read formatted data from a file
提问by goldenmean
As my learning, I am trying to use c++ ifstream and its operator>> to read data from a text file using code below. The text file outdummy.txt has following contents:
作为我的学习,我正在尝试使用 c++ ifstream 及其运算符>> 使用下面的代码从文本文件中读取数据。文本文件 outdummy.txt 有以下内容:
just dummy
Hello ofstream
555
My questions is how to read char data present in the file into a char array or string. How to do this using the ifstream::operator>> in code below.
我的问题是如何将文件中存在的字符数据读入字符数组或字符串。如何使用下面代码中的 ifstream::operator>> 来做到这一点。
#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;
}
回答by Kerrek SB
If you want to use formatted input, you have to know in advance what data to expect and read it into variables of the according data type. For example, if you know that the number is always the fifth token, as in your example, you could do this:
如果您想使用格式化输入,您必须事先知道期望的数据并将其读入相应数据类型的变量中。例如,如果您知道数字始终是第五个标记,如您的示例所示,您可以这样做:
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;
}
On the other hand, if you know that the number is always on the third line, by itself:
另一方面,如果你知道数字总是在第三行,那么:
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;
}
As you can see, to read a token as a string, you just stream it into a std::string
. It's important to remember that the formatted input operator works token by token, and tokens are separated by whitespace (spaces, tabs, newlines). The usual fundamental choice to make is whether you process a file entirely in tokens (first version), or line by line (second version). For line-by-line processing, you use getline
first to read one line into a string, and then use a string stream to tokenize the string.
如您所见,要将令牌作为字符串读取,只需将其流式传输到std::string
. 重要的是要记住格式化的输入运算符逐个标记地工作,并且标记由空格(空格、制表符、换行符)分隔。通常要做出的基本选择是完全以令牌(第一个版本)还是逐行(第二个版本)处理文件。对于逐行处理,您getline
首先使用将一行读入字符串,然后使用字符串流来标记该字符串。
A word about validation: You cannot know whether a formatted extraction will actually succeed, because that depends on the input data. Therefore, you should alwayscheck whether an input operation succeeded, and abort parsing if it doesn't, because in case of a failure your variables won't contain the correct data, but you have no way of knowing that later. So always say it like this:
关于验证的一句话:您无法知道格式化提取是否真的会成功,因为这取决于输入数据。因此,您应该始终检查输入操作是否成功,如果不成功则中止解析,因为如果失败,您的变量将不会包含正确的数据,但您以后无法知道。所以总是这样说:
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! */ }
The latter construction is usually used in a while
loop, to read an entire file line by line:
后一种结构通常用于while
循环中,以逐行读取整个文件:
while (std::getline(in, line)) { /* process line */ }
回答by Marcelo Cantos
ifstream
hasios_base::in
by default. You don't need to specify it.operator>>
can be invoked directly as an operator:in >> a
.- Reading strings is the same:
in >> s
, but the caveat is that it is whitespace-delimited, so it will read "just" by itself, without "dummy". - If you want to read complete lines, use
std::getline(in, s)
.
ifstream
有ios_base::in
默认。您不需要指定它。operator>>
可以直接作为运算符调用:in >> a
。- 读取字符串是一样的:
in >> s
,但需要注意的是它是用空格分隔的,所以它会自己“只是”读取,没有“虚拟”。 - 如果要阅读完整的行,请使用
std::getline(in, s)
.
回答by jonsca
Since you have elected to use C-strings, you can use the getlinemethod of your ifstream
object (not std::getline()
which works with std::string
s), which will allow you to specify the C-string and a maximum size for the buffer.
由于您选择使用 C 字符串,您可以使用对象的getline方法ifstream
(不适std::getline()
用于std::string
s),这将允许您指定 C 字符串和缓冲区的最大大小。
Based on what you had, and adding an additional buffer for the second line:
根据您拥有的内容,并为第二行添加额外的缓冲区:
char buf[100];
char buf2[100];
in.getline(buf,sizeof(buf));
in.getline(buf2,sizeof(buf2));
in >> a;
However, as the other poster has proposed, try using the std::string
and its methods, it will make your life easier.
然而,正如另一张海报所建议的,尝试使用std::string
和它的方法,它会让你的生活更轻松。
回答by npclaudiu
You can read file contents and use a Finite State Machinefor parsing.
您可以读取文件内容并使用有限状态机进行解析。
Example:
例子:
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());
}
Alternatively, you can use a tool like Flexto write your parser.
或者,您可以使用Flex 之类的工具来编写解析器。