从文件中读取多行字符串并将其存储在C ++中的字符串数组中

时间:2013-07-04 01:47:16

标签: c++ arrays string function

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

3 个答案:

答案 0 :(得分: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;
};

正如您所看到的,这些变化相当微小。

答案 1 :(得分: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中提供的示例,可能如下所示。

  

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提取到当前范围(通常是全局命名空间),并可能导致与标识符冲突。

答案 2 :(得分: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
  3. 你可以继续厌恶std::vector所有你想要的,但对于这样的场景,它是这项工作的最佳工具。