迭代文本文件并为每一行分配变量

时间:2014-11-12 05:19:10

标签: c++ object c++11 vector ifstream

很难找到一种方法将正在读取的文本文件的每一行分配给另一个变量,我在上面评论了变量,显示了显示该变量的文本文件中的一行是如何看的。我想知道我可以使用forloop以何种方式遍历整个文本文件,并根据需要存储的数据类型将数据存储到我上面评论的每个变量中。这三组变量都必须按物种存储,并且可以通过它们进行操作。如何将矢量分成一组三个变量?

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

string getInputFileName()
//retrieves the inputfile
{
    string fileName;
    ifstream inputfile;

    //prompting user for filename to be opened
    cout << "Enter the file name to be opened: ";
    cin >> fileName;

    //opening the file for input
    inputfile.open(fileName, ios::in);

    //checks to see if writing the input file failed
    if (inputfile.fail())
    {
        cout << "Opening file..." << fileName;
        cout << "\n";
        cout << "The " << fileName << "could not be opened! \n";
        cout << "1. Check if file exists. \n";
        cout << "2. Check file path. \n;";

    }
    else
    {
        cout << "File: " << fileName << " was successfully opened!" << endl;
        return fileName;
    }

}
string getOutputFileName()
//retrieves the inputfile
{
    string fileName;
    ofstream outputfile;

    //prompting user for filename to be opened
    cout << "Enter the file name to be opened: ";
    cin >> fileName;

    //opening the file for input
    outputfile.open(fileName, ios::in);

    //checks to see if writing the input file failed
    if (outputfile.fail())
    {
        cout << "Opening file..." << fileName;
        cout << "\n";
        cout << "The " << fileName << "could not be opened! \n";
        cout << "1. Check if file exists. \n";
        cout << "2. Check file path. \n;";

    }
    else
    {
        cout << "File: " << fileName << " was successfully opened!" << endl;
        return fileName;
    }

}


int main()
{
    //opens clasfication file
    ifstream inputFile(getInputFileName());

    //declaring year and numberOfSpecies
    int year, numberOfSpecies;
    string line;

    if (inputFile.is_open())
    {
        //year of file
        inputFile >> year;
        //echo for year
        cout << year << endl;

        //number of species of file
        inputFile >> numberOfSpecies;
        //echo for number of species
        cout << numberOfSpecies << endl;

        string line;

        //variables i need to assign line by line and be able to manipulate
        //region of species would look like this in text file: 84
        //nameOfspecies would like like this in the text file: Spotted Gecko
        //regionSightings would look like this in the text file: 84 95 30 25



        vector<string> linesOfData;

    for (int i = 0; (!inputFile.eof()) || (i <= numberOfSpecies) ; i++)
    {

        getline(inputFile, line, '\n');
        linesOfData.push_back(line);

        //echo vector!
        cout << linesOfData[i] << "\n";

        }
        ofstream outputFile(getOutputFileName());

    }

    return 0;
}

2 个答案:

答案 0 :(得分:1)

符合您要求的伪代码。您必须填写代码并执行所需的测试。 我已经多次使用类似的逻辑来满足我的要求。我认为这更易于维护和扩展。

class spotted_species{
    private:
        int first_val[];
        string species_name;
        int locations[];

    // Private methods
    private:
        void assign_species_firstVal (String first_line){
            Assign the first line after performing required transformations;
        }

        int  assign_species_name (String Second_Line){
            if (the species name exists in predefined array or file) {
                assign the name;
            }
            else {
                return -1; // to ignore all 3 lines. 
            }
        }

        void assign_species_locations (String third_line){
            tokenize by space
            convert each token to int and assign. hardly 2 lines code.
        }

    // Public methods
    public:
        void show_species(){
            std::cout<< "First val";
            std::cout<< "Species name";
            std::cout<< "Spotted locations";
        }

        int init(String firstline, String secondline, String ThirdLine){
            assign_species_firstVal(firstline);

            int status = assign_species_name (secondline);
            if (status) {
                assign_species_locations (ThirdLine);
            }

            return status_accordingly;
        }
}


int main(int argc, char *argv[])
{
    // Create an array of spotted_species to ensure you can hold the required number of 
    // species from the file. 
    run a OS command "WC -l" which gives the total number of line in your file. 
    All file handling could be done here based on the output of the above command. 

    // Calculate the number of objects you would need based on the number of lines. 
    // Rough estimate would be fine for these requirements.   
    int num_species = lines_in_file/3 + 10; // +10 is used to be on safer side. 

    // Create the objects
    spotted_species species_spotted_in_africa[num_species];

    int ctr;
    while (read file until the last line)
        // Read 3 lines at a go, 
        // store them in 3 variables. 
        // call init with all 3 arguments. 
    }

    // Now you have all the species information in seperate objects. 
    // you can access them in a loop or by any other means.

    // If you need to perform any additional processing on these objects, 
    //     you always can extend this class or 
    //     you could write another class which can process this class data. 

    // Flexible, simple, Maintainable and scalable. 
    return 0;
}

您必须根据具体要求进行一些更改。我希望这会有所帮助。

答案 1 :(得分:0)

基于每个物种有3行数据的事实,例如:

84
Spotted Gecko
84 95 30 25

我建议使用vectorstruct值而不是string值,其中每个struct包含单个物种的数据。在循环输入文件时,一次读取3行,将它们解析为struct的实例,然后将其推送到vector

试试这个:

#include "stdafx.h"

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

struct species
{
    int region;
    string name;
    std::vector<int> regionSightings;
};

bool openInputFile(ifstream &inputfile)
{
    string fileName;

    //prompting user for filename to be opened
    cout << "Enter the input file to be opened: ";
    getline(cin, filename);

    //opening the file for input
    cout << "Opening file: " << filename << endl;
    inputfile.open(fileName);

    //checks to see if opening the input file failed
    if (!inputfile)
    {
        cout << "File: " << fileName << " could not be opened!" << endl;
        cout << "1. Check if file exists." << endl;
        cout << "2. Check file path." << endl;

        return false;
    }

    cout << "File: " << fileName << " was successfully opened!" << endl;
    return true;
}

bool openOutputFile(ofstream &outputfile)
{
    string fileName;

    //prompting user for filename to be opened
    cout << "Enter the output file to be opened: ";
    getline(cin, filename);

    //opening the file for input
    cout << "Opening file: " << fileName << endl;
    outputfile.open(fileName);

    //checks to see if opening the output file failed
    if (!outputfile)
    {
        cout << "File: " << fileName << " could not be opened!" << endl;
        cout << "1. Check if file exists." << endl;
        cout << "2. Check file path." << endl;

        return false;
    }

    cout << "File: " << fileName << " was successfully opened!" << endl;
    return true;
}

int main()
{
    //opens clasfication file
    ifstream inputFile;
    if (openInputFile(inputFile))
    {
        //declaring year and numberOfSpecies
        int year, numberOfSpecies;
        string line;

        //year of file
        inputFile >> year;
        //echo for year
        cout << "Year: " << year << endl;

        //number of species in file
        inputFile >> numberOfSpecies;
        //echo for number of species
        cout << "# species: " << numberOfSpecies << endl;

        //there are three lines per species
        //region of species, eg: 84
        //nameOfspecies, eg: Spotted Gecko
        //regionSightings, eg: 84 95 30 25

        vector<species> speciesData;

        for (int i = 0; i < numberOfSpecies; ++i)
        {
            species s;

            if (!getline(inputFile, line))
            {
                cout << "File: " << fileName << " could not read a species region!" << endl;
                break;
            }

            if (!(istringstream(line) >> s.region))
            {
                cout << "File: " << fileName << " could not parse a species region!" << endl;
                break;
            }

            if (!getline(inputFile, s.name))
            {
                cout << "File: " << fileName << " could not read a species name!" << endl;
                break;
            }

            if (!getline(inputFile, line))
            {
                cout << "File: " << fileName << " could not read a species sightings!" << endl;
                break;
            }

            istringstream iss(line);
            int num;

            while (iss >> num)
                s.regionSightings.push_back(num);

            if (!iss.eof())
            {
                cout << "File: " << fileName << " could not parse a species sightings!" << endl;
                break;
            }

            speciesData.push_back(s);

            //echo vector!
            cout << s.region << " " << s.name << " " << line << endl;
        }

        cout << "Closing input file" << endl;
        inputFile.close();

        ofstream outputFile;
        if (openOutputFile(outputFile))
        {
            for (std::vector<species>::iterator iter = speciesData.begin();
                iter != speciesData.end();
                ++iter)
            {
                species &s = *iter;

                // write species data to outputFile as needed...
            }

            cout << "Closing output file" << endl;
        }

        cout << "Finished" << endl;
    }

    return 0;
}