C++ 使用stringstream逐行读取文件两次

C++ 使用stringstream逐行读取文件两次,c++,fstream,ifstream,stringstream,C++,Fstream,Ifstream,Stringstream,我需要一行一行地读两遍文件。文件内容应适合内存。因此,我通常会将整个文件读入一个缓冲区,然后使用该缓冲区 但是,因为我想使用std::getline,所以我需要使用std::basic\u istream。所以,我觉得写这篇文章是个好主意 std::ifstream file(filepath); std::stringstream ss; ss << file.rdbuf(); for (std::string line; std::getline(ss, line);) { }

我需要一行一行地读两遍文件。文件内容应适合内存。因此,我通常会将整个文件读入一个缓冲区,然后使用该缓冲区

但是,因为我想使用
std::getline
,所以我需要使用
std::basic\u istream
。所以,我觉得写这篇文章是个好主意

std::ifstream file(filepath);
std::stringstream ss;
ss << file.rdbuf();

for (std::string line; std::getline(ss, line);)
{
}
std::ifstream文件(filepath);
std::stringstream-ss;

ss在第一次循环后,清除EOF和失败位,然后返回到
stringstream
的开头,方法是:

ss.clear();
ss.seekg(0, std::ios::beg);
我猜
ss
我是否正确,因此需要提出另一种方法

你说得不对。“母鸡”也是毫无根据的。问题中没有足够的信息,但我怀疑问题与使用流缓冲区无关

在不知道第一个“垃圾”字符是什么的情况下,我不能肯定地说,但我怀疑该文件采用的是宽字符unicode格式,并且您使用的访问操作对宽字符不起作用。如果是这种情况,缓冲文件与问题无关

作为一个实验,尝试以下方法。当心w

    std::wifstream file(filepath);
    std::wstringstream ss;
    ss << file.rdbuf();

    for (int i = 0; i < 42; ++i) {
        wchar_t ch;
        ss >> ch;
        std::cout << static_cast<unsigned>(ch) << ' ';
    }
std::wifstream文件(filepath);
std::wstringstream ss;
ss>ch;

std::您是否需要在第二个循环之前返回到
ss
的开头。为什么不简单地
for(std::string-line;std::getline(file,line);){}
为什么需要stringstream?为什么不第一次将它读入字符串向量,然后您可以使用向量进行第二个循环。@KillzoneKid他不想从文件中读取两次,他想将其缓存在内存中的字符串流中。我想
ss有没有更好的方法从
ss
中提取行<代码>标准::获取行(ss,行)将导致内存分配和数据复制。这似乎效率低下。也许有一种解决方案使用
std::string\u视图
?无法避免内存分配和复制数据。它从磁盘或其他东西开始,然后在内存中结束。与从磁盘读取数据相比,在内存中复制连续数据实际上是免费的。优化的唯一方法是测量实际应用程序的性能。但正如我所说,我怀疑您的实际问题与使用streambuf有关。我认为该程序将Unicode文件视为US-ASCII。试试我建议的实验。@JiveDadson我想你误解我了。我的意思是(在
ss之后)
    std::wifstream file(filepath);
    std::wstringstream ss;
    ss << file.rdbuf();

    for (int i = 0; i < 42; ++i) {
        wchar_t ch;
        ss >> ch;
        std::cout << static_cast<unsigned>(ch) << ' ';
    }