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

发布于 2024-12-05 02:46:37 字数 564 浏览 3 评论 0原文

作为我的学习,我尝试使用 c++ ifstream 及其运算符>>使用下面的代码从文本文件读取数据。文本文件 outdummy.txt 具有以下内容:

just dummy
Hello ofstream
555

我的问题是如何将文件中存在的字符数据读取到字符数组或字符串中。如何使用 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;
}

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:

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.

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不必在意 2024-12-12 02:46:37

如果要使用格式化输入,则必须提前知道需要什么数据并将其读入相应数据类型的变量中。例如,如果您知道数字始终是第五个标记(如示例所示),您可以执行以下操作:

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 */ }

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.


A word about validation: You cannot know whether a formatted extraction will actually succeed, because that depends on the input data. Therefore, you should always check 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 (std::getline(in, line)) { /* process line */ }
那片花海 2024-12-12 02:46:37
  1. ifstream 默认情况下有 ios_base::in。您不需要指定它。
  2. operator>> 可以直接作为运算符调用:in >>一个。
  3. 读取字符串也是一样的: in >> s,但需要注意的是它是空格分隔的,因此它本身会读取“just”,而不是“dummy”。
  4. 如果您想读取完整的行,请使用 std::getline(in, s) 。
  1. ifstream has ios_base::in by default. You don't need to specify it.
  2. operator>> can be invoked directly as an operator: in >> a.
  3. 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".
  4. If you want to read complete lines, use std::getline(in, s).
或十年 2024-12-12 02:46:37

由于您选择使用 C 字符串,因此可以使用 getline 方法ifstream 对象(不是与 std::string 一起使用的 std::getline()),这将允许您指定C 字符串和缓冲区的最大大小。

根据您所拥有的,并为第二行添加一个额外的缓冲区:

char buf[100];
char buf2[100];

in.getline(buf,sizeof(buf));
in.getline(buf2,sizeof(buf2));
in >> a;

但是,正如另一位发帖者所建议的那样,尝试使用 std::string 及其方法,这将使您的生活更轻松。

Since you have elected to use C-strings, you can use the getline method of your ifstream object (not std::getline() which works with std::strings), which will allow you to specify the C-string and a maximum size for the buffer.

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.

情定在深秋 2024-12-12 02:46:37

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

示例:

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 之类的工具来编写解析器。

You can read file contents and use a Finite State Machine for 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 Flex to write your parser.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文