Pregunta

How do I read in lines from a file and assign specific segments of that line to the information in structs? And how can I stop at a blank line, then continue again until end of file is reached?

Background: I am building a program that will take an input file, read in information, and use double hashing for that information to be put in the correct index of the hashtable.

Suppose I have the struct:

struct Data
{
    string city;
    string state;
    string zipCode;
};

But the lines in the file are in the following format:

20

85086,Phoenix,Arizona
56065,Minneapolis,Minnesota

85281
56065

I cannot seem to figure this out. I am having a really hard time reading in the file. The first line is basically the size of the hash table to be constructed. The next blank line should be ignored. Then the next two lines are information that should go into the struct and be hashed into the hash table. Then another blank line should be ignored. And finally, the last two lines are input that need to be matched to see if they exist in the hash table or not. So in this case, 85281 is not found. While 56065 is found.

This is what I have and it doesn't seem to be doing what I want it to do:

int main(int argc, char *argv[])
{
string str;

//first line of file is size of hashtable
getline(cin, str);

stringstream ss(str);
int hashSize;
ss >> hashSize;

//construct hash table
Location *hashTable = new Location[hashSize];

//skip next line
getline(cin, str);
string blank = " ";
while(getline(cin, str))
{


    {
        //next lines are data
        Location locate;

        string line;
        getline(cin, line);
        istringstream is(line);
        getline(is, locate.zipCode, ',');
        getline(is, locate.city, ',');
        getline(is, locate.state, ',');

    insertElementIntoHash(hashTable, locate, hashSize);
    }
}
    dispHashTable(hashTable, hashSize);

//read third set of lines that check if the zipCodes are in the hashtable or not
while(getline(cin, str))
{
    //stop reading at a blank line or in this case, end of file


    stringstream is(str);
    string searchZipCode;
    is >> searchZipCode;

    searchElementInHash(hashTable, hashSize, searchZipCode);
}


//delete hash table after use

delete []hashTable;

return 0;
}
¿Fue útil?

Solución

You might read the input this way:

#include <iostream>
#include <sstream>
#include <vector>

struct Location
{
    std::string city;
    std::string state;
    std::string zipCode;
};

int main(int argc, char *argv[]) {

    std::istringstream input(
        "2\n"
        "\n"
        "85086,Phoenix,Arizona\n"
        "56065,Minneapolis,Minnesota\n"
        "\n"
        "85281\n"
        "56065\n"
    );

    // Make the size unsigned, to avoid signed/unsigned compare warnings.
    unsigned hashSize;

    std::string line;
    getline(input, line);
    std::istringstream hash_line(line);
    // Ignore white space.
    if( ! (hash_line >> hashSize >> std::ws && hash_line.eof())) {
        std::cerr << "Error: Invalid file format [1].\n" << line << '\n';
        return -1;
    }
    else {
        getline(input, line);
        std::istringstream first_blank_line(line);
        // Ignore white space.
        first_blank_line >> std::ws;
        if( ! first_blank_line.eof()) {
            // Missing blank line.
            std::cerr << "Error: Invalid file format [2].\n" << line << '\n';
            return -2;
        }
        else {
            // Have a local variable (No need to allocate it)
            // (Is it a hash table !???)
            std::vector<Location> hashTable;
            hashTable.reserve(hashSize);

            while(hashTable.size() < hashSize && getline(input, line)) {
                std::istringstream data_line(line);

                Location locate;

                getline(data_line, locate.zipCode, ',');
                getline(data_line, locate.city, ',');
                getline(data_line, locate.state); // Note: No comma here.
                if(data_line && data_line.eof()) {
                    // Note: The fields may have leading and/or trailing white space.
                    std::cout
                        << "Insert the location into the hash table.\n"
                        << locate.zipCode << '\n'
                        << locate.city << '\n'
                        << locate.state << '\n';
                    hashTable.push_back(locate);
                }
                else {
                    std::cerr << "Error: Invalid file format [3].\n" << line << '\n';
                    return -3;
                }
            }
            if(hashTable.size() != hashSize) {
                std::cerr << "Error: Invalid file format [4].\n";
                return -4;
            }
            else {
                getline(input, line);
                std::istringstream second_blank_line(line);
                // Ignore white space.
                second_blank_line >> std::ws;
                if( ! second_blank_line.eof()) {
                    // Missing blank line.
                    std::cerr << "Error: Invalid file format [5].\n";
                    return -5;
                }
                else {
                    std::string searchZipCode;
                    while(input >> searchZipCode) {
                        // Search element in the hash table
                    }
                }
            }
        }
    }
    return 0;
}

Otros consejos

Following modification should work:

//skip next line
getline(cin, str);
string blank = " ";
string line;
while(getline(cin, line) && (line != ""))
{


    {
        //next lines are data
        Location locate;

        istringstream is(line);
        getline(is, locate.zipCode, ',');
        getline(is, locate.city, ',');
        getline(is, locate.state, ',');

    insertElementIntoHash(hashTable, locate, hashSize);
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top