带有istream_iterator的程序正在崩溃

Program with istream_iterator is crashing down

本文关键字:崩溃 程序 istream iterator 带有      更新时间:2023-10-16

为什么我的程序崩溃了:

#ifndef StreamBuffer_h
#define StreamBuffer_h
#include <string>
#include <fstream>
#include <iostream>
#include <iterator>
using namespace std;
enum StreamBufferState
{
  STREAMBUFFER_OK = 0,
  STREAMBUFFER_EOF = 1
};
// gzip plik
// type plik | gzip -d
// gzip -d plik.gz
// gzip -dc plik.gz 
class StreamBuffer
{
    istream_iterator<char> iter;
    int maxBufferSize;
    std::string buffer;
 public:
    StreamBuffer(int maxBuffSize, bool streamInput, std::string filename="")
    {
    SetMaxBufferSize(maxBuffSize);
        if(streamInput) // Wejscie strumieniowe
            iter = istream_iterator<char>(std::cin);
        else // Wejscie plikowe
            iter = istream_iterator<char>(fstream(filename.c_str()));
    }
    ~StreamBuffer()
    {
    }
    void SetMaxBufferSize(unsigned int maxBuffSize)
    {
    maxBufferSize = maxBuffSize;
    }
    StreamBufferState FullBufferWithData()
    {
        char c;
        istream_iterator<char> iend;
        for(int i=0;i<maxBufferSize;++i)
        {
            if(iter==iend)
                return STREAMBUFFER_EOF;
            c << *iter;
            buffer += c; // !!!!!! In this line program is crashing down
            iter++;
        }
        return STREAMBUFFER_EOF;
    }
    std::string GetDataBuffer()
    {
    return buffer;
    }
};
#endif

错误:运行时检查失败 #3 - 正在使用变量"c"而未初始化。

有错误的行:

buffer += c; // !!!!!! In this line program is crashing down

[编辑]改进我的代码后,我有:

#ifndef StreamBuffer_h
#define StreamBuffer_h
#include <string>
#include <fstream>
#include <iostream>
#include <iterator>
using namespace std;
enum StreamBufferState
{
  STREAMBUFFER_OK = 0,
  STREAMBUFFER_EOF = 1
};
// gzip plik
// type plik | gzip -d
// gzip -d plik.gz
// gzip -dc plik.gz 
class StreamBuffer
{
    fstream file;
    istream_iterator<char> iter;
    int maxBufferSize;
    std::string buffer;
 public:
    StreamBuffer(int maxBuffSize, bool streamInput, std::string filename="")
    {
    SetMaxBufferSize(maxBuffSize);
        if(streamInput) // Wejscie strumieniowe
            iter = istream_iterator<char>(std::cin);
        else // Wejscie plikowe
        {
            file.open(filename.c_str(),ios::in);
            iter = istream_iterator<char>(file);
        }
    }
    ~StreamBuffer()
    {
        file.close();
    }
    void SetMaxBufferSize(unsigned int maxBuffSize)
    {
    maxBufferSize = maxBuffSize;
    }
  StreamBufferState FullBufferWithData()
    {
        char c;
        istream_iterator<char> iend;
        for(int i=0;i<maxBufferSize;++i)
        {
            if(iter==iend)
                return STREAMBUFFER_EOF;
            c = *iter;
            buffer += c;
            iter++;
        }
        return STREAMBUFFER_EOF;
    }
    std::string GetDataBuffer()
    {
        string buf = buffer;
        buffer.clear();
        return buf;
    }
};
#endif

我还有另一个问题:当我使用流迭代器读取字符时,新行(和空格)被忽略,为什么?

没什么可说的,但是...

istream_iterator您正在使用临时 ( fstream ),将在完整结束时销毁表达,给iter留下一个悬而未决的参考。

当然,你永远不会初始化c(这是未定义的行为),但我怀疑这不是你真正的原因崩溃。 你c << *iter做什么? (它是什么实际上所做的是尝试从破坏中提取一个角色流,然后将未定义的值c移动到左---未定义的行为(如果 *iter 的值更大)比一个int ---,中的位数,最后扔掉班次的结果。

如果我猜你想正确做什么,惯用的方法是这样的:

class StreamBuffer
{
    std::filebuf myFile;
    std::istream myIStream;
    std::string  myBuffer;
    int myMaxBufferSize;
public:
    StreamBuffer(int maxBufferSize, std::string const& filename )
        : myIStream( filename.empty() ? std::cin.rdbuf() : &myFile )
        , myMaxBufferSize( maxBufferSize )
    {
        if ( ! filename.empty() ) {
            myFile.open( filename.c_str() );
            if ( ! myFile.is_open() ) {
                //  throw ?
            }
        }
    }
    StreamBufferState FillBufferWithData()
    {
        char c;
        while ( myBuffer.size() < myMaxBufferSize && myIStream >> c ) {
            myBuffer += c;
        }
        return myIStream ? STREAMBUFFER_OK : STREAMBUFFER_EOF;
    }
};

除了我真的怀疑这是你想要的:它将任何错误视为文件结尾,当您报告文件结束时部分填充缓冲区,最重要的是,它(就像 istream_iterator<char> ) 跳过空格。

如果你能准确地指定你想做什么,也许我们可以提供更多帮助。