一次读取输入文件并写入输出文件,跳过 getline() 中的行
Reading Input file and writing to output file one section at a time, skipping lines in getline()
我是 C++ 的新手,在使用 getline() 命令跳过输入文件中的行时遇到困难,我不确定我的问题是什么。
该程序的目标是一次读入一个“部分”的输入文件,将其放入一个结构中,然后将该行输出到文件,并继续直到文件中不再有任何行。
输入文件如下所示:
000.000.0000
lastname
street
city
state
zipcode
firstname
000.000.0000
lastname
street
....
等...
当我 运行 程序时,它输出到 out 文件,但它会跳过并继续重复这些相同的行,直到我强行停止程序。
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <climits>
using namespace std;
struct Person
{
string firstName;
string lastName;
string phoneNumber;
};
struct Address
{
string streetNum_Name;
string city;
string state;
int zip_code;
};
struct Info
{
Person person;
Address address;
};
void printFileHeader(ofstream& outFile);
bool openInputFile(ifstream& inFile);
void openOutputFile(ofstream& outFile);
struct Info readInfo(ifstream& inFile, Info&);
void printInfo(ofstream& outFile, Info&);
int main()
{
ifstream inFile;
ofstream outFile;
bool fileStreamState;
Info person;
printFileHeader(outFile);
fileStreamState = openInputFile(inFile);
openOutputFile(outFile);
cout << "Processing information. Please Wait...." << endl << endl;
while (fileStreamState) {
readInfo(inFile, person);
printInfo(outFile, person);
}
outFile << setw(7) << "-----" << setw(20) << "---------" << setw(15) << "----------" << setw(20) << "----"
<< setw(12) << "------------" << endl;
cout << "Program has finished execution." << endl;
inFile.close();
outFile.close();
}
void printFileHeader(ofstream& outFile) {
outFile << left << setw(7) << "Entry" << setw(20) << "Last Name" << setw(15) << "First Name" << setw(20) << "City"
<< setw(12) << "Phone Number" << endl;
outFile << setw(7) << "-----" << setw(20) << "---------" << setw(15) << "----------" << setw(20) << "----"
<< setw(12) << "------------" << endl;
}
bool openInputFile(ifstream& inFile) {
string filename;
cout << "Enter the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
inFile.open(filename.c_str());
while(inFile.fail()) {
cout << string(15,'*') << " File Open Error " << string(15,'*') << endl;
cout << "==> Input file failed to open properly!!\n";
cout << "==> Attempted to open file: " << filename << endl;
cout << "==> Try Again\n";
cout << string(47,'*') << endl<< endl;
inFile.clear();
cout << "Enter in the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
inFile.open(filename.c_str());
}
return 1;
}
void openOutputFile(ofstream& outFile) {
string filename;
cout << "Enter the name of the output file: ";
cin >> filename;
cout << filename << endl << endl;
outFile.open(filename.c_str());
while(outFile.fail()) {
cout << string(15,'*') << " File Open Error " << string(15,'*') << endl;
cout << "==> Output file failed to open properly!!\n";
cout << "==> Attempted to open file: " << filename << endl;
cout << "==> Try Again\n";
cout << string(47,'*') << endl<< endl;
outFile.clear();
cout << "Enter in the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
outFile.open(filename.c_str());
}
}
struct Info readInfo(ifstream& inFile, Info& record) {
getline(inFile, record.person.phoneNumber);
cout << record.person.phoneNumber << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.person.lastName);
cout << record.person.lastName << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.address.streetNum_Name);
cout << record.address.streetNum_Name << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.address.city);
cout << record.address.city << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.address.state);
cout << record.address.state << endl;
inFile.ignore(INT_MAX, '\n');
inFile >> record.address.zip_code;
cout << record.address.zip_code << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.person.firstName);
cout << record.person.firstName << endl;
return record;
}
void printInfo(ofstream& outFile, Info& record) {
static int entry = 0;
entry++;
outFile << left << setw(7) << entry << setw(20) << record.person.lastName << setw(15) << record.person.firstName
<< setw(20) << record.address.city << setw(12) << record.person.phoneNumber << endl;
}
非常感谢任何帮助,谢谢!
您正在 ignore()
中 readInfo()
中的数据,您不应忽略这些数据。 getline()
读取直到 的所有内容,包括 换行符,然后丢弃换行符。因此,您正在读取 phoneNum
数据,然后 ignore()
读取 lastName
数据,然后读取 streetNum
数据,然后 ignore()
读取 city
数据等。您需要删除 getline()
之后的所有 ignore()
,您唯一需要的 ignore()
是阅读 zip_code
之后的那个operator>>
:
struct Info readInfo(ifstream& inFile, Info& record) {
getline(inFile, record.person.phoneNumber);
cout << record.person.phoneNumber << endl;
getline(inFile, record.person.lastName);
cout << record.person.lastName << endl;
getline(inFile, record.address.streetNum_Name);
cout << record.address.streetNum_Name << endl;
getline(inFile, record.address.city);
cout << record.address.city << endl;
getline(inFile, record.address.state);
cout << record.address.state << endl;
inFile >> record.address.zip_code;
inFile.ignore(INT_MAX, '\n');
cout << record.address.zip_code << endl;
getline(inFile, record.person.firstName);
cout << record.person.firstName << endl;
return record;
}
话虽如此,您在 main()
中的 while
循环已损坏。一旦 readInfo()
读取了文件中的最后一条记录,如果最后一条 firstName
以换行符结尾,则 EOF 尚未到达,因此 while (fileStreamState)
仍将评估为 true 并且循环将再次调用 readInfo()
和 printInfo()
,即使没有更多的记录数据留给 read/print.
没有充分的理由让 readInfo()
以 struct
作为参考,并且 return 也如此。所以你应该 return a bool
而不是指示 success/fail:
bool readInfo(ifstream& inFile, Info&);
...
while (readInfo(inFile, person)) {
printInfo(outFile, person);
}
...
bool readInfo(ifstream& inFile, Info& record) {
getline(inFile, record.person.phoneNumber);
cout << record.person.phoneNumber << endl;
getline(inFile, record.person.lastName);
cout << record.person.lastName << endl;
getline(inFile, record.address.streetNum_Name);
cout << record.address.streetNum_Name << endl;
getline(inFile, record.address.city);
cout << record.address.city << endl;
getline(inFile, record.address.state);
cout << record.address.state << endl;
inFile >> record.address.zip_code;
inFile.ignore(INT_MAX, '\n');
cout << record.address.zip_code << endl;
getline(inFile, record.person.firstName);
cout << record.person.firstName << endl;
return !inFile.fail();
}
给出的完整工作程序 below 显示了如何实现您想要的。我已经对您给定的代码片段进行了一些更正。主要变化包括使用 std::vector
来存储信息以及仅调用 readInfo()
和 printInfo()
一次,而不是在 while 循环中一次又一次地调用它们。使用向量的优点是您可以将该向量用于以后的目的(如果有的话)。
#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <climits>
#include <vector>
using namespace std;
struct Person
{
string firstName ;
string lastName;
string phoneNumber;
};
struct Address
{
string streetNum_Name;
string city;
string state;
int zip_code = 70; //always initialize built in type in block/local scope
};
struct Info
{
Person person;
Address address;
};
void printFileHeader(ofstream& outFile);
bool openInputFile(ifstream& inFile);
void openOutputFile(ofstream& outFile);
void readInfo(ifstream& inFile, std::vector<Info>&);
void printInfo(ofstream& outFile, std::vector<Info>&);
int main()
{
ifstream inFile;
ofstream outFile;
bool fileStreamState;
std::vector<Info> infoVec; //this vector will contain all the information
//Info person; //no need for this anymore since we have the vector
//printFileHeader(outFile);//call this after openOutputFile()
fileStreamState = openInputFile(inFile);
openOutputFile(outFile);
printFileHeader(outFile);
cout << "Processing information. Please Wait...." << endl << endl;
readInfo(inFile, infoVec) ; //call readInfo once instead of calling again and again
printInfo(outFile, infoVec);//call printInfo once instead of calling again and again
outFile << setw(7) << "-----" << setw(20) << "---------" << setw(15) << "----------" << setw(20) << "----"
<< setw(12) << "------------" << endl;
cout << "Program has finished execution." << endl;
inFile.close();
outFile.close();
}
void printFileHeader(ofstream& outFile) {
outFile << left << setw(7) << "Entry" << setw(20) << "Last Name" << setw(15) << "First Name" << setw(20) << "City"
<< setw(12) << "Phone Number" << endl;
outFile << setw(7) << "-----" << setw(20) << "---------" << setw(15) << "----------" << setw(20) << "----"
<< setw(12) << "------------" << endl;
}
bool openInputFile(ifstream& inFile) {
string filename;
cout << "Enter the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
inFile.open(filename.c_str());
while(inFile.fail()) {
cout << string(15,'*') << " File Open Error " << string(15,'*') << endl;
cout << "==> Input file failed to open properly!!\n";
cout << "==> Attempted to open file: " << filename << endl;
cout << "==> Try Again\n";
cout << string(47,'*') << endl<< endl;
inFile.clear();
cout << "Enter in the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
inFile.open(filename.c_str());
}
return 1;
}
void openOutputFile(ofstream& outFile) {
string filename;
cout << "Enter the name of the output file: ";
cin >> filename;
cout << filename << endl << endl;
outFile.open(filename.c_str());
while(outFile.fail()) {
cout << string(15,'*') << " File Open Error " << string(15,'*') << endl;
cout << "==> Output file failed to open properly!!\n";
cout << "==> Attempted to open file: " << filename << endl;
cout << "==> Try Again\n";
cout << string(47,'*') << endl<< endl;
outFile.clear();
cout << "Enter in the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
outFile.open(filename.c_str());
}
}
void readInfo(ifstream& inFile, std::vector<Info> &infoVec) {
std::string temporaryZipCode;
Info info;
while(getline(inFile, info.person.phoneNumber,'\n'),
getline(inFile, info.person.lastName,'\n'),
getline(inFile, info.address.streetNum_Name,'\n'),
getline(inFile, info.address.city,'\n'),
getline(inFile, info.address.state,'\n'),
getline(inFile, temporaryZipCode, '\n'),
getline(inFile, info.person.firstName,'\n')
)
{
std::istringstream ss(temporaryZipCode);
ss >> info.address.zip_code;
infoVec.emplace_back(info);
}
}
void printInfo(ofstream& outFile, std::vector<Info> &infoVec) {
int entry = 0; //no need for making it static
for(const Info& record: infoVec )
{
outFile << left << setw(7) << entry << setw(20) << record.person.lastName << setw(15) << record.person.firstName
<< setw(20) << record.address.city << setw(12) << record.person.phoneNumber << endl;
entry++;
}
}
可以看到上面程序的输出here。我在对您的程序进行更改的任何地方都添加了评论。
我是 C++ 的新手,在使用 getline() 命令跳过输入文件中的行时遇到困难,我不确定我的问题是什么。 该程序的目标是一次读入一个“部分”的输入文件,将其放入一个结构中,然后将该行输出到文件,并继续直到文件中不再有任何行。
输入文件如下所示:
000.000.0000
lastname
street
city
state
zipcode
firstname
000.000.0000
lastname
street
....
等... 当我 运行 程序时,它输出到 out 文件,但它会跳过并继续重复这些相同的行,直到我强行停止程序。
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <climits>
using namespace std;
struct Person
{
string firstName;
string lastName;
string phoneNumber;
};
struct Address
{
string streetNum_Name;
string city;
string state;
int zip_code;
};
struct Info
{
Person person;
Address address;
};
void printFileHeader(ofstream& outFile);
bool openInputFile(ifstream& inFile);
void openOutputFile(ofstream& outFile);
struct Info readInfo(ifstream& inFile, Info&);
void printInfo(ofstream& outFile, Info&);
int main()
{
ifstream inFile;
ofstream outFile;
bool fileStreamState;
Info person;
printFileHeader(outFile);
fileStreamState = openInputFile(inFile);
openOutputFile(outFile);
cout << "Processing information. Please Wait...." << endl << endl;
while (fileStreamState) {
readInfo(inFile, person);
printInfo(outFile, person);
}
outFile << setw(7) << "-----" << setw(20) << "---------" << setw(15) << "----------" << setw(20) << "----"
<< setw(12) << "------------" << endl;
cout << "Program has finished execution." << endl;
inFile.close();
outFile.close();
}
void printFileHeader(ofstream& outFile) {
outFile << left << setw(7) << "Entry" << setw(20) << "Last Name" << setw(15) << "First Name" << setw(20) << "City"
<< setw(12) << "Phone Number" << endl;
outFile << setw(7) << "-----" << setw(20) << "---------" << setw(15) << "----------" << setw(20) << "----"
<< setw(12) << "------------" << endl;
}
bool openInputFile(ifstream& inFile) {
string filename;
cout << "Enter the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
inFile.open(filename.c_str());
while(inFile.fail()) {
cout << string(15,'*') << " File Open Error " << string(15,'*') << endl;
cout << "==> Input file failed to open properly!!\n";
cout << "==> Attempted to open file: " << filename << endl;
cout << "==> Try Again\n";
cout << string(47,'*') << endl<< endl;
inFile.clear();
cout << "Enter in the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
inFile.open(filename.c_str());
}
return 1;
}
void openOutputFile(ofstream& outFile) {
string filename;
cout << "Enter the name of the output file: ";
cin >> filename;
cout << filename << endl << endl;
outFile.open(filename.c_str());
while(outFile.fail()) {
cout << string(15,'*') << " File Open Error " << string(15,'*') << endl;
cout << "==> Output file failed to open properly!!\n";
cout << "==> Attempted to open file: " << filename << endl;
cout << "==> Try Again\n";
cout << string(47,'*') << endl<< endl;
outFile.clear();
cout << "Enter in the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
outFile.open(filename.c_str());
}
}
struct Info readInfo(ifstream& inFile, Info& record) {
getline(inFile, record.person.phoneNumber);
cout << record.person.phoneNumber << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.person.lastName);
cout << record.person.lastName << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.address.streetNum_Name);
cout << record.address.streetNum_Name << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.address.city);
cout << record.address.city << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.address.state);
cout << record.address.state << endl;
inFile.ignore(INT_MAX, '\n');
inFile >> record.address.zip_code;
cout << record.address.zip_code << endl;
inFile.ignore(INT_MAX, '\n');
getline(inFile, record.person.firstName);
cout << record.person.firstName << endl;
return record;
}
void printInfo(ofstream& outFile, Info& record) {
static int entry = 0;
entry++;
outFile << left << setw(7) << entry << setw(20) << record.person.lastName << setw(15) << record.person.firstName
<< setw(20) << record.address.city << setw(12) << record.person.phoneNumber << endl;
}
非常感谢任何帮助,谢谢!
您正在 ignore()
中 readInfo()
中的数据,您不应忽略这些数据。 getline()
读取直到 的所有内容,包括 换行符,然后丢弃换行符。因此,您正在读取 phoneNum
数据,然后 ignore()
读取 lastName
数据,然后读取 streetNum
数据,然后 ignore()
读取 city
数据等。您需要删除 getline()
之后的所有 ignore()
,您唯一需要的 ignore()
是阅读 zip_code
之后的那个operator>>
:
struct Info readInfo(ifstream& inFile, Info& record) {
getline(inFile, record.person.phoneNumber);
cout << record.person.phoneNumber << endl;
getline(inFile, record.person.lastName);
cout << record.person.lastName << endl;
getline(inFile, record.address.streetNum_Name);
cout << record.address.streetNum_Name << endl;
getline(inFile, record.address.city);
cout << record.address.city << endl;
getline(inFile, record.address.state);
cout << record.address.state << endl;
inFile >> record.address.zip_code;
inFile.ignore(INT_MAX, '\n');
cout << record.address.zip_code << endl;
getline(inFile, record.person.firstName);
cout << record.person.firstName << endl;
return record;
}
话虽如此,您在 main()
中的 while
循环已损坏。一旦 readInfo()
读取了文件中的最后一条记录,如果最后一条 firstName
以换行符结尾,则 EOF 尚未到达,因此 while (fileStreamState)
仍将评估为 true 并且循环将再次调用 readInfo()
和 printInfo()
,即使没有更多的记录数据留给 read/print.
没有充分的理由让 readInfo()
以 struct
作为参考,并且 return 也如此。所以你应该 return a bool
而不是指示 success/fail:
bool readInfo(ifstream& inFile, Info&);
...
while (readInfo(inFile, person)) {
printInfo(outFile, person);
}
...
bool readInfo(ifstream& inFile, Info& record) {
getline(inFile, record.person.phoneNumber);
cout << record.person.phoneNumber << endl;
getline(inFile, record.person.lastName);
cout << record.person.lastName << endl;
getline(inFile, record.address.streetNum_Name);
cout << record.address.streetNum_Name << endl;
getline(inFile, record.address.city);
cout << record.address.city << endl;
getline(inFile, record.address.state);
cout << record.address.state << endl;
inFile >> record.address.zip_code;
inFile.ignore(INT_MAX, '\n');
cout << record.address.zip_code << endl;
getline(inFile, record.person.firstName);
cout << record.person.firstName << endl;
return !inFile.fail();
}
给出的完整工作程序 below 显示了如何实现您想要的。我已经对您给定的代码片段进行了一些更正。主要变化包括使用 std::vector
来存储信息以及仅调用 readInfo()
和 printInfo()
一次,而不是在 while 循环中一次又一次地调用它们。使用向量的优点是您可以将该向量用于以后的目的(如果有的话)。
#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <climits>
#include <vector>
using namespace std;
struct Person
{
string firstName ;
string lastName;
string phoneNumber;
};
struct Address
{
string streetNum_Name;
string city;
string state;
int zip_code = 70; //always initialize built in type in block/local scope
};
struct Info
{
Person person;
Address address;
};
void printFileHeader(ofstream& outFile);
bool openInputFile(ifstream& inFile);
void openOutputFile(ofstream& outFile);
void readInfo(ifstream& inFile, std::vector<Info>&);
void printInfo(ofstream& outFile, std::vector<Info>&);
int main()
{
ifstream inFile;
ofstream outFile;
bool fileStreamState;
std::vector<Info> infoVec; //this vector will contain all the information
//Info person; //no need for this anymore since we have the vector
//printFileHeader(outFile);//call this after openOutputFile()
fileStreamState = openInputFile(inFile);
openOutputFile(outFile);
printFileHeader(outFile);
cout << "Processing information. Please Wait...." << endl << endl;
readInfo(inFile, infoVec) ; //call readInfo once instead of calling again and again
printInfo(outFile, infoVec);//call printInfo once instead of calling again and again
outFile << setw(7) << "-----" << setw(20) << "---------" << setw(15) << "----------" << setw(20) << "----"
<< setw(12) << "------------" << endl;
cout << "Program has finished execution." << endl;
inFile.close();
outFile.close();
}
void printFileHeader(ofstream& outFile) {
outFile << left << setw(7) << "Entry" << setw(20) << "Last Name" << setw(15) << "First Name" << setw(20) << "City"
<< setw(12) << "Phone Number" << endl;
outFile << setw(7) << "-----" << setw(20) << "---------" << setw(15) << "----------" << setw(20) << "----"
<< setw(12) << "------------" << endl;
}
bool openInputFile(ifstream& inFile) {
string filename;
cout << "Enter the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
inFile.open(filename.c_str());
while(inFile.fail()) {
cout << string(15,'*') << " File Open Error " << string(15,'*') << endl;
cout << "==> Input file failed to open properly!!\n";
cout << "==> Attempted to open file: " << filename << endl;
cout << "==> Try Again\n";
cout << string(47,'*') << endl<< endl;
inFile.clear();
cout << "Enter in the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
inFile.open(filename.c_str());
}
return 1;
}
void openOutputFile(ofstream& outFile) {
string filename;
cout << "Enter the name of the output file: ";
cin >> filename;
cout << filename << endl << endl;
outFile.open(filename.c_str());
while(outFile.fail()) {
cout << string(15,'*') << " File Open Error " << string(15,'*') << endl;
cout << "==> Output file failed to open properly!!\n";
cout << "==> Attempted to open file: " << filename << endl;
cout << "==> Try Again\n";
cout << string(47,'*') << endl<< endl;
outFile.clear();
cout << "Enter in the name of the input file: ";
cin >> filename;
cout << filename << endl << endl;
outFile.open(filename.c_str());
}
}
void readInfo(ifstream& inFile, std::vector<Info> &infoVec) {
std::string temporaryZipCode;
Info info;
while(getline(inFile, info.person.phoneNumber,'\n'),
getline(inFile, info.person.lastName,'\n'),
getline(inFile, info.address.streetNum_Name,'\n'),
getline(inFile, info.address.city,'\n'),
getline(inFile, info.address.state,'\n'),
getline(inFile, temporaryZipCode, '\n'),
getline(inFile, info.person.firstName,'\n')
)
{
std::istringstream ss(temporaryZipCode);
ss >> info.address.zip_code;
infoVec.emplace_back(info);
}
}
void printInfo(ofstream& outFile, std::vector<Info> &infoVec) {
int entry = 0; //no need for making it static
for(const Info& record: infoVec )
{
outFile << left << setw(7) << entry << setw(20) << record.person.lastName << setw(15) << record.person.firstName
<< setw(20) << record.address.city << setw(12) << record.person.phoneNumber << endl;
entry++;
}
}
可以看到上面程序的输出here。我在对您的程序进行更改的任何地方都添加了评论。