读取带有分隔符的文件和用于散列程序的空行

时间:2014-03-11 08:02:19

标签: c++ file-io getline

如何读取文件中的行并将该行的特定段分配给结构中的信息?如何在空行处停止,然后再继续直到文件结束?

背景:我正在构建一个程序,它将获取一个输入文件,读入信息,并使用双重哈希将该信息放入哈希表的正确索引中。

假设我有结构:

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

但文件中的行格式如下:

20

85086,Phoenix,Arizona
56065,Minneapolis,Minnesota

85281
56065

我似乎无法弄清楚这一点。我在阅读文件时非常困难。第一行基本上是要构造的哈希表的大小。应忽略下一个空白行。然后接下来的两行是应该进入结构并被散列到哈希表中的信息。然后应该忽略另一个空白行。最后,最后两行是需要匹配的输入,以查看它们是否存在于哈希表中。所以在这种情况下,找不到85281。虽然发现56065。

这就是我所拥有的,似乎没有做我想做的事情:

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;
}

2 个答案:

答案 0 :(得分:0)

以下修改应该有效:

//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);
    }
}

答案 1 :(得分:0)

您可以通过这种方式阅读输入:

#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;
}