getline和提取运算符的问题 [英] Problems with getline and extraction operators
问题描述
文本文件
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屋!