getline和提取运算符的问题 [英] Problems with getline and extraction operators

查看:86
本文介绍了getline和提取运算符的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文本文件

Excalibur
150
Throwing Stars
15
Rapier
200
Bow and Arrow
100


我的文本读取代码


My code to read them by text

...
struct Weapon
{
    char name[MAXNAME];
    int strength;
};
...
Weapon wp[WPNUM];
ifstream infile;
...
for (int i = 0; i < WPNUM; i++)
{
    infile.getline(wp[i], MAXNAME, '\n');
    cout << wp[i].name << endl;
    infile >> wp[i].strength;
    cout << wp[i].strength << endl;
}
...


但这是行不通的.有人可以帮忙吗?提前谢谢.

更改标题以反映问题的实质,并消除了一些多余的内容.


But it doesn''t work. Anyone can help? Thanks in advance.

Changed the title to reflect what the problem really is and got rid of some superfluous stuff.

推荐答案

有两个我在这里可以看到的问题:

-您无需检查文件的末尾或流中是否有其他问题.
-您正在使用getline的成员版本,请改用免费功能版本
-在流上使用提取器不会删除任何空格,因此getline将读取空字符串

使用类似的内容:

There''s a couple of problems I can see here:

- you''re not checking for the end of the file or something else going wrong with the stream.
- you''re using the member version of getline, use the free function version instead
- using an extractor on a stream doesn''t remove any white-space after it so getline will be reading an empty string

Use something like:

int read_integer_from_stream( std::istream &from )
{
	int n; from >> n;
	std::string rest_of_line;
	std::getline( from, rest_of_line );
	return n;
}



哦,不要使用数组,这不是1994年.请尝试使用std :: vector和std :: string-它们要安全得多.假定实际上将要使用的武器使它成为一门课.

讲道结束:-)

PS:实际上,这还不是讲道的结尾...看一下前面的解决方案并批评它不是C ++,而是C和C ++的混蛋,我想我应该把钱花在嘴边,然后敲门.关于如何解决问题的快速思路:



Oh, and don''t use arrays, this isn''t 1994. Try using std::vector and std::string - they''re far safer. And presuming weapon''s actually going to be used for something make it a class.

End of sermon :-)

PS: Actually it''s not the end of the sermon... Looking at the previous solution and criticising it for not being C++ but a bastard breed of C and C++ I thought I should put my money where my mouth is and knock up a quick idea of how I''d approach the problem:

#include <sstream>
#include <vector>
#include <iterator>
#include <string>

int read_integer_from_stream( std::istream &from )
{
    int n; from >> n;
    std::string rest_of_line;
    std::getline( from, rest_of_line );
    return n;
}

class weapon
{
    public:
        weapon() : power_( 0 ){}

        weapon( std::istream &initialise_from )
        {
            std::getline( initialise_from, name_ );
            power_ = read_integer_from_stream( initialise_from );
        }

        weapon( weapon &©_me )
        {
            swap( std::move( copy_me ) );
        }

        weapon &operator=( const weapon ©_me )
        {
            weapon w( copy_me );
            swap( std::move( w ) );
            return *this;
        }

        weapon &operator=( weapon &©_me )
        {
            swap( std::move( copy_me ) );
            return *this;
        }

        std::string name() const
        {
            return name_;
        }

        bool is_more_powerful_than( const weapon &compare_against ) const
        {
            return power_ > compare_against.power_;
        }

        void swap( weapon &&swap_with )
        {
            std::swap( swap_with.name_,  name_  );
            std::swap( swap_with.power_, power_ );
        }

        friend std::ostream &operator<<( std::ostream &, const weapon & );
        friend std::ostream &operator>>( std::istream &, const weapon & );

    private:
        std::string name_;
        int power_;
};

std::ostream &operator<<( std::ostream &str, const weapon &w )
{
    return str << w.name_ << '\n' << w.power_ << '\n';
}

std::istream &operator>>( std::istream &str, weapon &to_modify )
{
    weapon w( str );
    to_modify.swap( std::move( w ) );
    return str;
}

void weapon_test( std::ostream &output )
{
    std::istringstream input( "Sword\n87\nAxe\n88\n" );
    std::vector<weapon> weapons;

    typedef std::istream_iterator<weapon> input_iter;
    typedef std::ostream_iterator<weapon> output_iter;
    std::copy( input_iter( input ), input_iter(), std::back_inserter( weapons ) );
    std::copy( begin( weapons ), end( weapons ), output_iter( output, "" ) );
}


现实生活中还有一些可怕的事情我不会做:

-所有功能都是内联的
-对于流格式,我还不够宽容,每种武器都必须以换行符结尾,即使最后一个也要换行
-我没有使用PIMP
-测试工具很简单,说实话,废话.并非每种行为都经过测试(尽管它们相当琐碎)
-该类与测试位于同一文件中
-没有非会员掉期

好点是(他谦虚地说...)

-无手动循环
-类可以应付大多数事物的内在价值可以
-具有例外安全分配操作员
-拥有移动构造函数和赋值运算符(近来非常重要)

大量修改:要摆脱标签的影响并使其看起来更好一点,请修复由于白痴将旧版本粘贴在


There are still some horrible things in here I wouldn''t do it real life:

- All the functions are inline
- I''m not permissive enough about the stream format, each weapon has to end with a newline, even the last one
- I''m not using a PIMP
- The test harness is trival and, honestly, crap. Not every behaviour is tested (although they''re fairly trivial)
- The class is in the same file as the test
- No non-member swap

Good points are (he says modestly...)

- No manual loops
- Class can cope with most things an intrinsic value can
- Has an exception safe assignment operaor
- Has a move constructor and assignment operator (really important these days)

Numerous Edits: To get rid of tabs and make it look slightly better, fix loads of errors caused by idiot me pasting an old version in


中而导致的错误负载,说实话,我从来都不是c ++从流中提取格式化信息的方式的忠实拥护者.结果,我从来没有像他们那样精通过(也不需要如此).这是一些与您的输入数据配合使用的代码:


To be honest, I''ve never been a huge fan of c++''s way of extracting formatted info from a stream. As a result, I''ve never been terribly proficient(nor needed to be) with them. Here''s some code that works just fine with your input data:


#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

const int MAXLINE = 1024;

struct Weapon
{
    string name;
    int strength;
};

int main()
{
    char *szFilename = "test.txt";
    const int numWeapons = 4;
    int i;
    ifstream inputFile(szFilename);
    Weapon wpnRack[numWeapons];
    char lineBuffer[MAXLINE];

    for (i=0; i<4; i++)
    {
        inputFile.getline(lineBuffer, MAXLINE);
        wpnRack[i].name = lineBuffer;

        inputFile.getline(lineBuffer, MAXLINE);
        wpnRack[i].strength = atoi(lineBuffer);

        cout << wpnRack[i].name << endl;
        cout << "\t" << wpnRack[i].strength << endl;
    }
    inputFile.close();

    return 0;
}


输出:


Output:

Excalibur
        150
Throwing Stars
        15
Rapier
        200
Bow and Arrow
        100


这篇关于getline和提取运算符的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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