简单的C ++输入从文件...如何? [英] Simple C++ input from file...how to?

查看:146
本文介绍了简单的C ++输入从文件...如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个档案:

P 0.5 0.6 0.3
30 300
80 150
160 400
200 150
250 300
T
r  45 0 0
s 0.5 1.5 0 0
t 200 –150
.
.
.

当我阅读'P'时,我知道3个浮标会跟随。其后将是有限数量的X和Y坐标。数字将变化,直到达到一个T,我必须认识。然后可能有一个'r','s'或't'后面跟一些值。

When I read in 'P' I know that 3 floats will follow. That will be followed by a finite number of X and Y coordinates. The number will vary until a 'T' is reached which I have to recognize. Then there could be an 'r', 's' or 't' followed by some values.

无论如何,我知道如何识别'P' 2浮动,但是我知道我必须有一个while循环的X和Y坐标,这将停止,当我到一个'T'。我不知道C ++让循环停止,并识别'T',然后做别的事情。

Anyways I know how to recognize 'P' and then take in the 2 floats but then I know I have to have a while loop for the X and Y coordinates which will stop when I get to a 'T'. I do not know enough about C++ to make the loop stop and recognize the 'T' and then do something else.

一个例子来解释将不胜感激。提前感谢!

An example to explain would be appreciated. Thanks in advance!

推荐答案

我会告诉你我认为这是正确的C ++方式。首先定义一个类来表示你的第一行和做它的IO:

I'll show you what I think it's the proper C++ way of doing this. First define a class for representing your first line and for doing its IO:

struct FirstLine
{
    double x, y, z;
    friend std::istream & operator>>(std::istream & is, FirstLine & data)
    {
        std::string line, ignore;
        std::getline(is, line);
        std::istringstream iss(line);
        iss >> ignore >> data.x >> data.y >> data.z;
        assert(ignore == "P" && iss);
        return is;
    }
    friend std::ostream & operator<<(std::ostream & os, FirstLine const & data)
    {
        return os << "P " << data.x << " " << data.y << " " << data.z;
    }    
};

我添加了一些基本的错误检查与assert,你可能会想要一个更强大的最终程序。

I've added some basic error checking with assert, you'll probably want something more robust in your final program.

现在一个类用于中间行:

Now a class for middle lines:

struct MiddleLine
{
    double x, y;
    friend std::istream & operator>>(std::istream & is, MiddleLine & data)
    {
        std::string line;
        std::getline(is, line);
        if(line == "T")
            is.clear(std::ios::failbit);
        else
        {
            int n = sscanf(line.c_str(), "%lf %lf", &data.x, &data.y);
            assert(n == 2);
        }
        return is;
    }
    friend std::ostream & operator<<(std::ostream & os, MiddleLine const & data)
    {
        return os << data.x << " " << data.y;
    }    
};

当我们到达中间行的结束部分时,我们应该遇到一个T 。在这种情况下,我们提高流的失败位,这将告诉客户端没有更多的中间行可以读取。

When we reach the end of the section where the middle lines are we are supposed to encounter a "T". In that case we raise the fail bit of the stream, which will tell client that there are no more middle lines to read.

最后一行最后一行: / p>

Finally a class for the last lines:

struct LastLine
{
    std::string identifier; // r, s or t
    std::vector<double> values;
    friend std::istream & operator>>(std::istream & is, LastLine & data)
    {
        std::string line;
        std::getline(is, line);
        std::istringstream iss(line);
        iss >> data.identifier;
        assert(data.identifier == "r" || data.identifier == "s" 
               || data.identifier == "t");
        std::copy(std::istream_iterator<double>(iss), 
                  std::istream_iterator<double>(), std::back_inserter(data.values));
        return is;
    }
    friend std::ostream & operator<<(std::ostream & os, LastLine const & data)
    {
        os << data.identifier << " ";
        std::copy(data.values.begin(), data.values.end(),
                  std::ostream_iterator<double>(os, " "));
        return os;
    }      
};

最后一行更复杂,因为我们不知道每个值中有多少个值,所以我们阅读尽可能多。

Last lines are more complicated becase we don't know how many values are in each, so we just read as many as we can.

这是棘手的部分。现在我们的主函数只读取一个第一行,然后是未知数量的中间行,最后是未知数量的最后一行:

That was the tricky part. Now our main function will simply read one first line, then an unknown number of middle lines, and finally an unknown number of last lines:

int main()
{
    std::string const data = "P 0.5 0.6 0.3\n
                             "30 300\n"
                             "80 150\n"
                             "160 400\n"
                             "200 150\n"
                             "250 300\n"
                             "T\n"
                             "r  45 0 0\n"
                             "s 0.5 1.5 0 0\n"
                             "t 200 –150";

    std::istringstream iss(data);

    FirstLine first_line;
    iss >> first_line;

    std::vector<MiddleLine> middle_lines;
    std::copy(std::istream_iterator<MiddleLine>(iss), 
              std::istream_iterator<MiddleLine>(), 
              std::back_inserter(middle_lines));
    iss.clear();

    std::vector<LastLine> last_lines;
    std::copy(std::istream_iterator<LastLine>(iss), 
              std::istream_iterator<LastLine>(), 
              std::back_inserter(last_lines));
    assert(iss.eof());       

    std::cout << first_line << "\n";
    std::copy(middle_lines.begin(), middle_lines.end(),
              std::ostream_iterator<MiddleLine>(std::cout, "\n"));
    std::copy(last_lines.begin(), last_lines.end(),
              std::ostream_iterator<LastLine>(std::cout, "\n"));
    return 0;
}

这是您将获得的输出::

This is the output you'll get::

P 0.5 0.6 0.3
30 300
80 150
160 400
200 150
250 300
r 45 0 0
s 45 0 0 0.5 1.5 0 0
t 45 0 0 0.5 1.5 0 0 200

我使用一个字符串作为我的数据源,但你可能想从一个文件中读取。

I've used a string as the source of my data but you'll probably want to read from a file.

这样,你可以看到我没有写一个循环。

And that's all, you can see that I didn't write a single loop.

这是代码在键盘。

这篇关于简单的C ++输入从文件...如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆