如何从文件中读取行并将其切割成碎片?
Posted
技术标签:
【中文标题】如何从文件中读取行并将其切割成碎片?【英文标题】:How can I read lines from file and cut it pieces? 【发布时间】:2013-12-14 17:32:48 【问题描述】:[编辑]
我指定了我的问题,也许它有更多信息:
我有一个包含很多行的文件,例如“string1 string2 int1 int2”,所以一行包含两个字符串和两个整数。我想逐行读取文件并将这四个数据推送到我的结构的向量中(它具有相同的变量类型和 num )。我的问题是,我该怎么做,因为 >> 运算符无论如何都不起作用。也不是 getline()。
和代码:
void FromFile(string filename)
ifstream stream;
stream.open(filename);
adatok adattemp;
while(stream.good())
stream >> adattemp.agresszor >> adattemp.vedo >> adattemp.haborukezdete >> adattemp.haboruvege >> ws;
cout << adattemp.agresszor;
vektor.push_back(adattemp);
stream.close();
【问题讨论】:
当你说“string string int int”时,每个字符串是一个单词,还是用引号括起来的字符串? 我会使用std::vector
是的,是两个单词和两个数字(4位/数字)。
您还有问题吗?您可以尝试打开流的异常,以便查看发生的任何错误:在打开文件之前输入“stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
”。
【参考方案1】:
假设每个字符串只是一个单词,这应该可行:
#include <vector>
#include <string>
#include <fstream>
struct Entry
std::string s1;
std::string s2;
int i1;
int i2;
;
std::vector<Entry> entries;
int main()
std::ifstream file("yourfile");
while (file.good())
Entry entry;
file >> entry.s1 >> entry.s2 >> entry.i1 >> entry.i2 >> std::ws;
entries.push_back(entry);
return 0;
注意:在阅读每一行的末尾包含>> std::ws
很重要。它占用了额外的空白。否则,您最终会在文件末尾添加一个额外的垃圾条目。
编辑:正如 Simple 在 cmets 中指出的那样,如果在读取文件时发生任何错误,上述代码将在 vector
的末尾存储一个垃圾条目。此代码将通过确保在存储条目之前没有错误来解决此问题:
Entry entry;
while (file >> entry.s1 >> entry.s2 >> entry.i1 >> entry.i2 >> std::ws)
entries.push_back(entry);
【讨论】:
这不是读取输入的正确循环。它应该更像:Entry entry; while (file >> entry.s1 >> entry.s2 >> entry.i1 >> entry.i2 >> std::ws) entries.push_back(entry);
代码正确。这只是风格问题。优化编译器应该为两种形式生成相同的机器代码。
不,这是不正确的。您的代码会将无效数据插入vector
。这不是优化问题。
它不会插入无效数据。为什么会这样?两者之间唯一真正的区别是,在您的版本中,循环条件隐式为while (!file.fail())
,而我的是while (file.good())
。除此之外,两者在语义上是等价的,并导致相同的行为。
它们完全不同。您的代码首先检查流中是否仍有内容,然后尝试从中读取四个内容,然后将它们插入到向量中而不检查读取是否成功。我的尝试读取这四件事,然后检查这些读取后流是否仍然有效,如果是则插入它们。【参考方案2】:
我会重载>>
并使用std::copy
#include<vector>
#include<algorithm>
//...
struct Reader
std::string str1;
std::string str2;
int int1;
int int2;
friend std::istream& operator << (std::istream& is, Reader &r)
return is >> r.str1 >> r.st2 >> r.int1 >> r.int2 ;
;
std::vector<Reader> vec;
std::ifstream fin("file_name");
std::copy(std::istream_iterator<Reader>(fin),
std::istream_iterator<Reader>(),
std::back_inserter(vec)
) ;
假设所有字符串和整数都用空格分隔
您也可以重载>>
以类似方式显示内容
【讨论】:
【参考方案3】:由于您不知道文件大小,因此矢量会更适合 IMO。
while ( myFile >> string1 >> string2 >> myInt1 >> myInt2 )
stringvec1.push_back( string1 );
stringvec2.push_back( string2 );
intvec1.push_back( myInt1 );
intvec2.push_back( myInt2 );
编辑:
如果您正在阅读的 4 个变量对应于一个特定的具有逻辑意义的类,那么您可以拥有一个类/结构向量,其中所有这 4 个作为成员。
类似:
struct myFileVariables
std:string m_string1;
std:string m_string2;
int m_myInt1;
int m_myInt2;
myFileVariables ( string string1, string string2, int myInt1, int myInt2 ) :
m_string1( string1 ), m_string2( string2 ), m_myInt1( myInt1 ),
m_myInt2( myInt2 )
;
在你的主要功能中:
while ( myFile >> string1 >> string2 >> myInt1 >> myInt2 )
myFileVariables newEntry( string1, string2, myInt1, myInt2 );
myVec.push_back( newEntry );
【讨论】:
为什么不是适当定义的struct
s 向量?
数组的大小是多少?
我的意思是矢量,当然。 (但是你也可以在没有向量的情况下使用动态数组,所以没关系——你认为向量如何发挥它们的魔力?)——重点是“为什么不是结构”?
我有一个包含四个变量(两个字符串和整数)的结构,我从这个结构中创建了一个向量。非常感谢您的回答:)
这个循环将每一行都放入向量中(以及如何拆分它)?以上是关于如何从文件中读取行并将其切割成碎片?的主要内容,如果未能解决你的问题,请参考以下文章