【问题标题】:Reading multiple lines of strings from a file and storing it in string array in C++从文件中读取多行字符串并将其存储在 C++ 中的字符串数组中
【发布时间】:2013-07-04 01:47:16
【问题描述】:

我有一个名为 StringList 的类,它由一个构造函数和一个析构函数组成。我所追求的是我的程序即使在它没有运行之后也能够将其字符串保留在数组中。我想要这样做的方法是让我的构造函数从文件中读取字符串并将它们存储到我的字符串数组(str [])中。我的析构函数会将我当前的字符串保存到我的文件中。创建内存时,我无法从文件中读取和存储。我希望每个单词都是数组中的一个元素。 例如,在正在读取的文件中,字符串是这样存储的:

HELLO
MOM
DAD
FOUR
YELLOW

我希望每个单词都是一个槽。换句话说。 str[0] = HELLO,str[1]= MOM,str[2]=DAD 等等。

这是我的构造函数:

StringList::StringList()
{
    numberOfStrings=0;
    str = new string[1000000];

ifstream myfile ("Read.txt");
 if (myfile.is_open())
    {
        for (int i = 0; i < 1000000; i++)
        {
            getline(myfile,str[i]);
            numberOfString++;


        }

        myfile.close();
    }


}

这里的问题是 for (int i=0; i

【问题讨论】:

  • 您可以先去掉newdelete,然后使用矢量来存储它们,并根据需要自动调整大小。

标签: c++ arrays string function


【解决方案1】:

NumberOfStrings++ 在您阅读时位于您的 for 循环之外(即它只会增加一次)。另外请考虑使用std::vector&lt;std::string&gt; 而不是动态数组。

这是使用 std::vector 而不是数组的代码版本:

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

class StringList
{
public:
    StringList(): str(1000000), numberOfStrings(0)
    {
        std::ifstream myfile ("Read.txt");
        if (myfile.is_open())
        {
            for (int i = 0; i < str.size(); i++)
            {
                getline(myfile, str[i]);
                numberOfStrings++;
            }

            myfile.close();
        }
    }

    StringList::~StringList()
    {
        std::ofstream os("Read.txt");
        for (int i = 0; i <numberOfStrings; i++) 
        {
            os << str[i] << std::endl;
        }
    }

private:
    std::vector<std::string> str;
    int numberOfStrings;
};

如您所见,变化非常小。

【讨论】:

  • @Borgleader 对不起,但这不适用于我的程序。我的程序的目的是围绕一个包含 1000000 个字符串的字符串数组。它已经实现了多个使用这个 str[] 的函数,我不想重写所有函数以适应 vector。反正有没有用我的方式来做。抱歉没有提到这是我的原帖
  • @WestonBuckeye: vector&lt;string&gt;string[] 的工作方式几乎相同,您仍然可以使用 vec[1]vec[10000] 访问元素,但是在使用 vector 而不是动态时,您会获得额外的好处大批。矢量可以自动调整大小,并为您处理内存管理。
  • 好吧,你可以继续使用数组,你的问题是为什么只有一个字符串被读取/写入,那是因为 numberOfStrings 在循环之外增加了。这是回答和修复。使用矢量是一个强烈建议的改进。
  • @Borgleader 我知道是对的。除了复制和粘贴之外,完全没有做任何事情的努力。阿西宁。
  • @WestonBuckeye:这里的好人不是读心术的人。几乎总是假设您不会以这种方式受到限制。看看人们在哪里执行他们自己的列表等问题,这里的许多人似乎很愚蠢。如果您受到某些标题或语言功能的限制,请务必在您的帖子中进行说明。否则,为了完全帮助您,您经常会收到可能无用/无用的建议。
【解决方案2】:

numberOfStrings 变量仅在 for 循环完成后更新一次。您还可以通过检查getline 的返回值是否失败来简化此操作,而无需指定要读取的大量行。如果您尝试读取文件末尾的 getline 将返回 false。

numberOfStrings = 0;
str = new std::string[1000000];
std::ifstream myfile("Read.txt");
if (myfile.is_open())
{
    std::string line;
    while(getline(myfile, str[numberOfStrings]))
        numberOfStrings++;
    myfile.close();
}

您可以使用std::vector 进一步简化此操作。要扩展您的答案StringList 中提供的示例,可能如下所示。

字符串列表.h

#include <vector>
#include <string>

class StringList
{
public:
    StringList();
    void PrintWords();
private:
    size_t numberOfLines;
    std::vector<std::string> str;
};

StringList.cpp 以单行方式读入每个字符串

#include "StringList.h"
#include <fstream>

StringList::StringList()
{
    std::ifstream myfile("Read.txt");
    if (myfile.is_open())
    {
        std::string line;
        while(getline(myfile, line))
        {
            lines_.push_back(line);
        }
        myfile.close();
    }
    numberOfLines = str.size();
}

StringList.cpp 使用std::istream_itertorstd::copy 将单个单词读入每个字符串

#include "StringList.h"
#include <fstream>
#include <istream>
#include <algorithm> // std::copy
#include <iterator>  // istream_iterator

StringList::StringList()
{
    std::ifstream myfile("Read.txt");
    if (myfile.is_open())
    {
        std::copy(
            istream_iterator<string>(myfile),
            istream_iterator<string>(),
            back_inserter(str));
    }
    numberOfLines = str.size();
}

其他一些打印单词的功能

StringList::PrintWords()
{
    for(size_t i = 0; i < numberOfLines; ++i)
    {
        std::cout << str[i] << std::endl;
    }
}

我还建议避免在代码中使用using namespace std。它将 std 中的所有内容拉入当前范围(通常是全局命名空间),并可能导致与标识符发生冲突。

【讨论】:

  • 对不起,我是编程初学者。你能告诉我如何在我的构造函数中正确地写它吗?我需要添加任何库才能使其正常工作吗?
  • 当您查看我在当前答案中链接到的文档时,我将添加一个示例;)
  • 什么文件?我只需要它从文件中读取并将每个单词存储到字符串数组中的一个槽中。我在哪里插入你给我看的东西
  • 无意识 对不起,但这不适用于我的程序。我的程序的目的是围绕一个包含 1000000 个字符串的字符串数组。它已经实现了多个使用这个 str[] 的函数,我不想重写所有函数以适应 vector。有没有办法用我的方式来做
  • @WestonBuckeye:无意冒犯,但您现在可能陷入困境,因为您没有使用std::vector
【解决方案3】:

这将是我读取数据的方法(这与其他答案不太一样,但只要您的单词表不包含带空格的单词,它应该可以正常工作)。

#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>

int main()
{
    std::fstream myFile("read.txt");
    if (myFile.is_open())
    {
        std::istream_iterator<std::string> iter(myFile), end;
        std::vector<std::string> str(iter, end);

        // print contents
        for (int i = 0; i < str.size(); i++)
            std::cout << i << ": " << str[i] << std::endl;
    }
}

参考资料:

  1. istream_iterator
  2. vector

你可以继续厌恶std::vector,但对于这种情况,它是完成这项工作的最佳工具。

【讨论】:

  • 此程序使用高级命令行接口。我没有 int main 也不想打印它的内容。
  • 我已经建议但将其删除,因为 OP 一次读取整行。甚至包括使用std::copy 来处理作为成员变量的向量;)并且甚至不要考虑包含除修改StringList之外的任何示例
  • @WestonBuckeye:这个答案的重点是说明如何使用完整的可编译程序读取文件的内容。这里只有四行代码实际上在做任何相关的事情。
猜你喜欢
  • 2021-07-13
  • 2014-02-06
  • 1970-01-01
  • 2014-09-25
  • 2021-10-25
  • 1970-01-01
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多