【问题标题】:Saving file contents to variables through >> operator通过 >> 运算符将文件内容保存到变量中
【发布时间】:2015-09-18 17:28:12
【问题描述】:

我正在尝试读取文件,然后将内容(以空格分隔)放入变量中。 文件的内容每行总是相似的。它看起来像这样:

(50,60) CIRCLE yellow 10
(100,160) CIRCLE red 20

这些值是位置、名称、颜色和直径。

这是我目前得到的:

#include <SFML/Graphics.hpp>
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Practicum week 3");
    std::ifstream input("input.txt");
    std::string name;
    std::string line;
    sf::Vector2f position;
    sf::Color colour;

    while (std::getline(input, line))
    {
        input >> position >> name;
    }

    while (window.isOpen()) {
        sf::Event Event;
        while (window.pollEvent(Event)) {
            if (Event.type == sf::Event::Closed) { window.close(); }
        }

        // Start frame
        window.clear();

        // End frame & display contents
        window.display();
    }

    return 0;
}

这里的问题是在input &gt;&gt; position &gt;&gt; name; 它给了我一个错误:

“错误:没有运算符 '>>' 匹配这些操作数” 操作数类型为:std::ifstream >> sf::vector2f

我已经看到很多解决这个问题的方法是缺少#include,但正如你所见,我已经解决了这个问题。

我错过了什么吗?

【问题讨论】:

  • 什么是sf::Vector2f?是否为它定义了operator &gt;&gt;
  • @Angew sf::Vector2f 是来自 SFML 的 (x,y) 向量,它基本上是我要绘制的对象的位置(但那是稍后的)。我没有重载 >> 运算符,因为我不确定我将如何去做。
  • Vector2f 没有重载operator &gt;&gt;,所以不能这样使用。
  • 好吧,如果你还没有为它编码 operator &gt;&gt;,而 SFML 也没有提供,你为什么期望使用 &gt;&gt; 工作?
  • @Angew 好吧,我不知道 SFML 必须提供一个。我以为我可以将 (10,20) 传递给 Vector2f。我应该将它发送到一个字符串,然后改为将其更改为 vector2f 吗?

标签: c++ string file-io operators


【解决方案1】:

以下示例将向您展示如何利用提取运算符重载,以便您的对象可以直接从流中读取值。

您需要为您的对象Vector2f 重载operator &gt;&gt;。这应该看起来像这样:

istream& operator>>(istream& is, const Vector2f& v2f)
{ 
    is >> v2f.data_member >> v2f.another_data_member;
    return is;
}

例如,要读取这种格式:(50,60) CIRCLE yellow 10,您的重载运算符应如下所示:*slightly in pseudo-code

istream& operator>>(istream& is, const Any_Object& any_obj_instantiation)
{ 
    // input variables
    int first_num, second_num;
    char open_par, close_par, comma;
    Circle circle;
    Color color;
    int last_num;
    // extract ; it skips whitespaces 
    is >> open_par >> first_num >> comma >> second_num >> cirlce >> color >> last_num;
    // failed input
    if(!is) return is;
    // wrong input format
    if(open_par != '(' || close_par != ')' || comma != ','){
        is.clear(ios_base::failbit);
        return is;
    }
    // pass the input values to the object 
    any_obj_instantiation(Vector2f(first_num, second_num), cirlce, color, last_num);

    return is;
}

上面的代码 sn-p 可以用作基准,并适应您要直接使用输入流运算符填充的对象。

【讨论】:

  • 我收到一条错误消息,指出 istream 和 Object 无法识别。我尝试检查我是否没有遗漏包含但在 google 上找不到这 2 个错误的任何内容。
  • @Aydin Biber 上述代码旨在作为基准。 (这就是为什么我要澄清:略用伪代码)。您只需将任何您想要的对象放在Object 的位置,并使用其成员调整主体。
  • @simplicis_veritatis 我不确定我是否理解为什么需要将任何内容传递给对象。我想读取文件并将其中的不同值保存到变量中。我需要制作我想在那里绘制的对象吗?我希望以后能在代码中做到这一点。
  • @Aydin Biber 我正在为答案添加一个澄清,但是,因为我们不知道您的对象的特殊性,例如Vector2f `color',具体代码我们写不出来。
  • @Aydin Biber 您可以从文件中通过引用要初始化的对象并使用相应的值填充它们,然后将它们保存在相同的容器中类型,而不是将文件中的所有值保存在不同的变量等中。
【解决方案2】:

字符串流呢?

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct vec{
    int x;
    int y;
};

int main() {
    //string s;
    //vec v;
    //stringstream ss;

    //ss << "20 10 test";
    //ss >> v.x >> v.y >> s;
    //cout << v.x << " " << v.y << " " << s.c_str(); // 20 10 test

    //@EDIT - simple parsing
    vec v;
    string s = "(2034,10)";
    size_t comaPos = s.find_first_of(',');
    string x = s.substr(1, comaPos-1);
    string y = s.substr(comaPos+1, s.find_first_of(')')-comaPos-1);

    v.x = stoi(x);
    v.y = stoi(y);

    cout << v.x << " " << v.y;

    return 0;
}

注意:您不能将“(20,10)”直接流式传输到 sf::Vector2f,但您可以只传输坐标,就像我在上面所做的那样。

【讨论】:

  • 遗憾的是它必须是“(10,20)”的形式。我不能以任何其他方式添加空格或分隔字符。
猜你喜欢
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多