【问题标题】:Stream extraction without white space - how to store list from text file into an array没有空格的流提取 - 如何将文本文件中的列表存储到数组中
【发布时间】:2020-04-30 04:03:32
【问题描述】:

假设我在文件 (names.txt) 中有一个这样的列表,其中不仅仅是 name1 name2 name3 name4 等,它有引号分隔字符串。

"玛丽","帕特里夏","琳达","芭芭拉","伊丽莎白","詹妮弗","玛丽亚","苏珊","玛格丽特","多萝西","丽莎", “南希”、“凯伦”、“贝蒂”

我正在使用这些方面的东西,但这只是将整个东西作为一个字符串存储到 array[0] 中,因为流提取只识别空白...

ifstream file("names.txt");
    if(file.is_open())
    {
        string array[50];

        for(int i = 0; i < 50; ++i)
        {
            file >> array[i];
        }
        cout << array[0];
    }

如何将每个名称以当前格式分隔为单独的字符串?

【问题讨论】:

标签: c++ arrays


【解决方案1】:

您可以逐个字符地读取文件。那么

  • 先等一开门”
  • 如果到达,更改模式并
  • 将字符复制到临时名称字符串中
  • 如果我们检测到关闭“,我们将名称复制到我们的名称向量并从头开始

信息。由于我们不知道名称的数量,我们使用动态增长的“数组”,即所谓的std::vector

请查看许多可能的示例之一:

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

int main() {

    // Open a file and check, if it is open
    if (std::ifstream fileStream("names.txt"); fileStream) {

        // Here we will store all names
        std::vector<std::string> names{};

        // This is for one name, we will build it character by character
        std::string name{};

        // We will read the file character wise
        char c{};

        // We build a little state machine. Either we wait for a starting " or we copy data
        bool copyCharacter{ false };

        // Read all characters from file. We could have also used while (fileStream.get(c))
        while (fileStream >> std::noskipws >> c) {

            // Are we waiting for the opening " or not
            if (!copyCharacter) {

                // We are waiting for the opening ". Check if we have read one.
                if (c == '\"') {

                    // We read an opening ". In the next step, we will copy the characters into the name
                    copyCharacter = true;
                }
            }
            else {
                // We are in copy mode. This will end with a closing ". Check, if we read one complete name
                if (c == '\"') {

                    // We found a closing " after a name. Therefore we stop this mode and wait for an opening " again
                    copyCharacter = false;
                    // We found a complete name. Add it to our target names
                    names.push_back(std::move(name));
                    // Temporary name will be reset, to be ready to read next name
                    name = {};
                }
                else {
                    // Copy mode. Add character to name
                    name += c;
                }
            }
        }
        // Show debug output
        std::cout << "\nWe have read " << names.size() << " names. Those are:\n\n";
        for (const std::string name : names) std::cout << name << '\n';
    }
    else {
        std::cerr << "\n\n***Error: Could not open source file\n";
    }
    return 0;
}

还有第二种可能。您可以使用逗号作为分隔符。有个函数std::getline

所以,首先按名称读取字符串名称,然后删除 ",然后将名称列表添加到我们的名称向量中:

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

int main() {

    // Open a file and check, if it is open
    if (std::ifstream fileStream("names.txt"); fileStream) {

        // Here we will store all names
        std::vector<std::string> names{};

        // This is for one name, including quotes
        std::string name{};

        // Read a complete name, until the next comma, include quotes
        while (std::getline(fileStream, name, ',')) {

            // Get the substring of name, without the quotes
            names.emplace_back(name.substr(1, name.size() - 2));
        }
        // Show debug output
        std::cout << "\nWe have read " << names.size() << " names. Those are:\n\n";
        for (const std::string name : names) std::cout << name << '\n';
    }
    else {
        std::cerr << "\n\n***Error: Could not open source file\n";
    }
    return 0;
}

而最高级和最复杂的解决方案是使用std::regex

但现在这可能太多了。

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

std::regex re{R"((\w+))"};
int main() {

    // Open a file and check, if it is open
    if (std::ifstream fileStream("names.txt"); fileStream) {

        // Here we will store all names
        std::vector<std::string> names{};

        // Read a complete line with all names in it
        for (std::string line{}; std::getline(fileStream, line);) {

            // Split the line in single names and copy the name to our names vector
            std::copy(std::sregex_token_iterator(line.begin(), line.end(), re), {}, std::back_inserter(names));
        }
        // Show debug output
        std::cout << "\nWe have read " << names.size() << " names. Those are:\n\n";
        for (const std::string name : names) std::cout << name << '\n';
    }
    else {
        std::cerr << "\n\n***Error: Could not open source file\n";
    }
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-15
    • 2023-02-10
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多