【问题标题】:Reading from a text file, best way to store data C++从文本文件中读取,存储数据的最佳方式 C++
【发布时间】:2014-06-04 17:31:59
【问题描述】:

基本上我有一个文本文件,我不需要读入其中的值,以便程序可以操作它们。

我正在使用 C++,并且我已经编写了工作代码来判断文件是否存在。

文本文件的格式如下:

1    7
8    10
20   6
3    14
...

左边的值是 X 值,右边的值是 Y 值。 (中间的空格是tab) 我如何提取这些数据?说将它们传递给这样的类...

myVector(X,Y);

另外,我想在我可以在类中使用它之前,我必须 TryParse 将它从字符串更改为 int 对吗? C++ 可以做到这一点吗?

谢谢!

【问题讨论】:

  • TryParse 是一个 C# 主义 - 你确定你在这里用 C++ 编程吗?
  • std::getline 在一个循环中。
  • 是的,我来自 C# 背景,我在那里使用过,但不知道是否可行
  • 它们是完全不同的语言。我会使用 scanf 或 cin。
  • 是的,我知道。这就是为什么我需要帮助解决这个问题。而 cin 对读取文件没有帮助?

标签: c++ file input tryparse


【解决方案1】:

这种解析可以用 boost.spirit 在一行中完成:

qi::phrase_parse(begin, end, *(qi::int_ > qi::int_ > qi::eol), qi::ascii::blank, v);

语法可以理解为:“尽可能多地读取一个 int,然后一个 int,然后是一个 EOL(行尾)(\n 或 \r\n,取决于语言环境)”。在整数和 EOL 之间可以找到空白字符(例如空格或制表符)。

优点:与 std::getline 循环相比,代码更清晰/简洁。 Spirit.qi 让您拥有更强大的控制力,而且您不需要 stoi 调用。 缺点:build-depends(不依赖于spirit.qi),编译时间。

#include <iostream>
#include <fstream>
#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace spirit = boost::spirit;
namespace qi = spirit::qi;

int main(int argc, char **argv)
{
  std::ifstream in(argv[1], std::ios_base::in);

  std::string storage;
  in.unsetf(std::ios::skipws);
  spirit::istream_iterator begin(in), end;

  std::vector<std::pair<int, int> > v;
  qi::phrase_parse(begin, end, *(qi::int_ > qi::int_ > qi::eol), qi::ascii::blank, v);

  for(const auto& p : v)
    std::cout << p.first << "," << p.second << std::endl;

  return 0;
}

【讨论】:

    【解决方案2】:

    如果我是你,我会写这样的东西。请注意,这只是原型代码,甚至没有经过测试。

    基本思想是在一行中读取两次,但使用不同的分隔符。您将首先使用制表符分隔符阅读,然后仅使用默认行结尾。

    当您没有更多要阅读的内容时,您需要确保优雅地退出循环,因此中断,尽管如果您的文件“正确”,第二个可能就足够了。

    您还需要确保转换为您的矢量类所期望的正确类型。我这里假设是 int,但如果是 string,则不需要我进行的转换。

    #include <string>
    #include <fstream>
    
    using namespace std;
    
    void yourFunction()
    {
        ..
        ifstream myfile("myfile.txt");
        string xword, yword;
        while (1) {
            if (!getline(myfile, xword, '\t'))
                break;
            if (!getline(myfile, yword))
                break;
            myVector.push_back(stoi(xword), stoi(yword));
        }
        ...
    }
    

    【讨论】:

    • 这就是你要找的东西,能解释一下你的“if”语句吗?我有点不确定那里在做什么
    • @user3012508:读完所有内容后,您需要退出循环。从理论上讲,如果您的文件“正确”,第二个 if 语句就足够了。
    • 它在 x 和 y 中的实际读数在哪里?我真的很感谢帮助
    • @user3012508 检查std:: getline 的文档,您会看到它返回一个istream &amp;。但是,如果您检查 istream 的引用,您会看到定义了到 bool 的转换,如果流中没有设置错误标志,则返回 false。如果设置了错误标志,则跳出循环。
    • @user3012508 在调用std:: getline 时读入这些值。请注意,xwordyword 被传递给 getline,它接受一个引用——它会修改这些值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 2011-10-27
    相关资源
    最近更新 更多