一次读取输入文件并写入输出文件,跳过 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();
}

Online Demo

给出的完整工作程序 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。我在对您的程序进行更改的任何地方都添加了评论。