C ++使用条件语句读取文本文件
C++ reading a text file with conditional statements
我正在尝试读取文本文件中的行,标记该行,然后继续对开关和中断块中的下一行执行相同的操作,但是在我的程序到达第一个中断后,它退出了循环并忽略文件的其余部分。
ifstream in("test.txt");
string line,buffer;
unsigned int firstLetter = 0;
//istringstream iss;
if( in.is_open() )
{
istringstream iss;
while(getline(in,line))
{
iss.str(line);
char firstChar = line.at( firstLetter );
switch ( firstChar )
{
case 'D':
while (getline(iss,buffer,'-'))
{//print each token, one per line
cout<<"buffer: "<<buffer<<" "<<endl;
}
break;
case 'R':
while ( getline(iss,buffer,'-') )
{cout<<"buffer: "<<buffer<<" "<<endl;}
break;
}
}
}
这是文本文件的内容:
D-Rise of the Titans-25.50-2009-12
D-23 Jump Street-20.00-2013-5
D-Home Alone-24.00-1995-16
D-Twin Warriors-24.00-2011-14
R-XXX-Pierce-Hawthorne-11-13
R-Forbidden Kingdom-Pierce-Hawthorne-13-31
R-23 Jump Street-Troy-Barnes-1-3
R-Home Alone-Shirley-Bennett-1-3
R-Modern Family-Abed-Nadir-10-66
但是当我 运行 我的代码时,我得到了这个:
buffer: D
buffer: Rise of the Titans
buffer: 25.50
buffer: 2009
buffer: 12
这是文本文件中第 1 行的内容,我怎样才能转到下一行并一直这样做直到文件末尾?
您正在更改 std::istringstream
对象的内容,但状态标志保持原样(即,您的 eof 位亮起)。一个示例,通过标准输入使用您的输入数据进行了修改:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
istream& in = std::cin;
string line,buffer;
istringstream iss;
while(getline(in,line))
{
if (!line.empty())
{
iss.str(line);
std::cout << "line at eof: " << iss.eof() << '\n';
char firstChar = line.at(0);
switch ( firstChar )
{
case 'D':
while (getline(iss,buffer,'-'))
cout<<"buffer: "<<buffer<<" "<<endl;
break;
case 'R':
while ( getline(iss,buffer,'-') )
cout<<"buffer: "<<buffer<<" "<<endl;
break;
}
}
}
}
输出
line at eof: 0
buffer: D
buffer: Rise of the Titans
buffer: 25.50
buffer: 2009
buffer: 12
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
要解决这个问题,要么在每次迭代之前清除流的状态,要么只是将字符串流移动到 while 循环中,使用该行进行初始化。前者在下面完成;我将后者作为练习留给您:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
istream& in = std::cin;
string line,buffer;
istringstream iss;
while(getline(in,line))
{
if (!line.empty())
{
iss.clear(); // <<=== ADDED HERE
iss.str(line);
std::cout << "line at eof: " << iss.eof() << '\n';
char firstChar = line.at(0);
switch ( firstChar )
{
case 'D':
while (getline(iss,buffer,'-'))
cout<<"buffer: "<<buffer<<" "<<endl;
break;
case 'R':
while ( getline(iss,buffer,'-') )
cout<<"buffer: "<<buffer<<" "<<endl;
break;
}
}
}
}
输出
line at eof: 0
buffer: D
buffer: Rise of the Titans
buffer: 25.50
buffer: 2009
buffer: 12
line at eof: 0
buffer: D
buffer: 23 Jump Street
buffer: 20.00
buffer: 2013
buffer: 5
line at eof: 0
buffer: D
buffer: Home Alone
buffer: 24.00
buffer: 1995
buffer: 16
line at eof: 0
buffer: D
buffer: Twin Warriors
buffer: 24.00
buffer: 2011
buffer: 14
line at eof: 0
buffer: R
buffer: XXX
buffer: Pierce
buffer: Hawthorne
buffer: 11
buffer: 13
line at eof: 0
buffer: R
buffer: Forbidden Kingdom
buffer: Pierce
buffer: Hawthorne
buffer: 13
buffer: 31
line at eof: 0
buffer: R
buffer: 23 Jump Street
buffer: Troy
buffer: Barnes
buffer: 1
buffer: 3
line at eof: 0
buffer: R
buffer: Home Alone
buffer: Shirley
buffer: Bennett
buffer: 1
buffer: 3
line at eof: 0
buffer: R
buffer: Modern Family
buffer: Abed
buffer: Nadir
buffer: 10
buffer: 66
问题是您迭代 istringstream 的内容直到失败。然后,您在其余行中重复使用相同的 istringstream。您需要清除其中的 fail/eof 位。
使用 iss.clear() 执行此操作。
#include <iostream>
#include <sstream>
#include <fstream>
int main(){
ifstream in('test.txt');
if (in.is_open()){
string line, buffer;
istringstream iss;
while (getline(in, line)){
iss.str(line);
iss.clear();
char c = line[0];
switch (c){
case 'D':
while (getline(iss, buffer, '-')){
cout << "buffer: " << buffer << endl;
}
break;
case 'R':
while (getline(iss, buffer, '-')){
cout << "buffer: " << buffer << endl;
}
break;
}
}
return 0;
}
我正在尝试读取文本文件中的行,标记该行,然后继续对开关和中断块中的下一行执行相同的操作,但是在我的程序到达第一个中断后,它退出了循环并忽略文件的其余部分。
ifstream in("test.txt");
string line,buffer;
unsigned int firstLetter = 0;
//istringstream iss;
if( in.is_open() )
{
istringstream iss;
while(getline(in,line))
{
iss.str(line);
char firstChar = line.at( firstLetter );
switch ( firstChar )
{
case 'D':
while (getline(iss,buffer,'-'))
{//print each token, one per line
cout<<"buffer: "<<buffer<<" "<<endl;
}
break;
case 'R':
while ( getline(iss,buffer,'-') )
{cout<<"buffer: "<<buffer<<" "<<endl;}
break;
}
}
}
这是文本文件的内容:
D-Rise of the Titans-25.50-2009-12
D-23 Jump Street-20.00-2013-5
D-Home Alone-24.00-1995-16
D-Twin Warriors-24.00-2011-14
R-XXX-Pierce-Hawthorne-11-13
R-Forbidden Kingdom-Pierce-Hawthorne-13-31
R-23 Jump Street-Troy-Barnes-1-3
R-Home Alone-Shirley-Bennett-1-3
R-Modern Family-Abed-Nadir-10-66
但是当我 运行 我的代码时,我得到了这个:
buffer: D
buffer: Rise of the Titans
buffer: 25.50
buffer: 2009
buffer: 12
这是文本文件中第 1 行的内容,我怎样才能转到下一行并一直这样做直到文件末尾?
您正在更改 std::istringstream
对象的内容,但状态标志保持原样(即,您的 eof 位亮起)。一个示例,通过标准输入使用您的输入数据进行了修改:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
istream& in = std::cin;
string line,buffer;
istringstream iss;
while(getline(in,line))
{
if (!line.empty())
{
iss.str(line);
std::cout << "line at eof: " << iss.eof() << '\n';
char firstChar = line.at(0);
switch ( firstChar )
{
case 'D':
while (getline(iss,buffer,'-'))
cout<<"buffer: "<<buffer<<" "<<endl;
break;
case 'R':
while ( getline(iss,buffer,'-') )
cout<<"buffer: "<<buffer<<" "<<endl;
break;
}
}
}
}
输出
line at eof: 0
buffer: D
buffer: Rise of the Titans
buffer: 25.50
buffer: 2009
buffer: 12
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
line at eof: 1
要解决这个问题,要么在每次迭代之前清除流的状态,要么只是将字符串流移动到 while 循环中,使用该行进行初始化。前者在下面完成;我将后者作为练习留给您:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
istream& in = std::cin;
string line,buffer;
istringstream iss;
while(getline(in,line))
{
if (!line.empty())
{
iss.clear(); // <<=== ADDED HERE
iss.str(line);
std::cout << "line at eof: " << iss.eof() << '\n';
char firstChar = line.at(0);
switch ( firstChar )
{
case 'D':
while (getline(iss,buffer,'-'))
cout<<"buffer: "<<buffer<<" "<<endl;
break;
case 'R':
while ( getline(iss,buffer,'-') )
cout<<"buffer: "<<buffer<<" "<<endl;
break;
}
}
}
}
输出
line at eof: 0
buffer: D
buffer: Rise of the Titans
buffer: 25.50
buffer: 2009
buffer: 12
line at eof: 0
buffer: D
buffer: 23 Jump Street
buffer: 20.00
buffer: 2013
buffer: 5
line at eof: 0
buffer: D
buffer: Home Alone
buffer: 24.00
buffer: 1995
buffer: 16
line at eof: 0
buffer: D
buffer: Twin Warriors
buffer: 24.00
buffer: 2011
buffer: 14
line at eof: 0
buffer: R
buffer: XXX
buffer: Pierce
buffer: Hawthorne
buffer: 11
buffer: 13
line at eof: 0
buffer: R
buffer: Forbidden Kingdom
buffer: Pierce
buffer: Hawthorne
buffer: 13
buffer: 31
line at eof: 0
buffer: R
buffer: 23 Jump Street
buffer: Troy
buffer: Barnes
buffer: 1
buffer: 3
line at eof: 0
buffer: R
buffer: Home Alone
buffer: Shirley
buffer: Bennett
buffer: 1
buffer: 3
line at eof: 0
buffer: R
buffer: Modern Family
buffer: Abed
buffer: Nadir
buffer: 10
buffer: 66
问题是您迭代 istringstream 的内容直到失败。然后,您在其余行中重复使用相同的 istringstream。您需要清除其中的 fail/eof 位。
使用 iss.clear() 执行此操作。
#include <iostream>
#include <sstream>
#include <fstream>
int main(){
ifstream in('test.txt');
if (in.is_open()){
string line, buffer;
istringstream iss;
while (getline(in, line)){
iss.str(line);
iss.clear();
char c = line[0];
switch (c){
case 'D':
while (getline(iss, buffer, '-')){
cout << "buffer: " << buffer << endl;
}
break;
case 'R':
while (getline(iss, buffer, '-')){
cout << "buffer: " << buffer << endl;
}
break;
}
}
return 0;
}