使用istream_iterator的程序崩溃了

时间:2014-04-01 13:33:27

标签: c++

为什么我的程序崩溃了:

#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 - 变量&#39; c&#39;正在使用而未被初始化。

有错误的行:

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

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

1 个答案:

答案 0 :(得分:1)

没有多少事情可以继续,但是......

您正在使用临时创建istream_iteratorfstream),将在完整结束时被破坏 表达式,让iter留下悬空参考。

当然,你永远不会初始化c(这是未定义的 行为),但我怀疑这不是你的原因 崩溃。你对c << *iter做了什么? (什么 实际上是尝试从被破坏的角色中提取一个角色 然后,将c中的未定义值移动到 left ---如果*iter的值更大,则为undefined行为 而不是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>)跳过空格。

如果你可以确切地说明你想要做什么,也许我们 可以提供更多帮助。