-2

我有一个名为 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<100000;i++) 行 这样做是继续将每个空格填充到元素中,直到达到 100000。如果我输入 i<20,它会读取所有内容并添加空格以填充到 20。无论如何要填充 txt 中实际字符串的数量。文件?

4

3 回答 3

4

NumberOfStrings++当您阅读时,它在您的 for 循环之外(即它只增加一次)。另外请考虑使用std::vector<std::string>而不是动态数组。

这是使用 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;
};

正如您所看到的,更改非常小。

于 2013-07-04T01:49:52.077 回答
1

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

std::istream_itertorStringList.cpp 使用and将单个单词读入每个字符串std::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当前范围(通常是全局命名空间)中拉出,并可能导致与标识符发生冲突。

于 2013-07-04T01:57:28.093 回答
0

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

#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所有你想要的,但对于这样的场景,它是完成这项工作的最佳工具。

于 2013-07-04T02:58:52.840 回答