2014-04-01 42 views
0

爲什麼我的程序轟然倒下:計劃與istream_iterator轟然倒下

#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 

Error: Run-Time Check Failure #3 - The variable 'c' is being used without being initialized.

行錯誤:

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 

I還有一個問題:當我用流迭代器讀取字符時,會忽略新的行(和空格),爲什麼?

+0

你爲什麼要在char上做二進制移位? – Geoffroy

+0

你應該閱讀[Eric Lippert的這篇博客文章](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/),瞭解如何調試諸如你的小程序。 –

+0

istream_iterator解引用並將其賦值給c變量會產生垃圾,但我不知道爲什麼。 – CppMonster

回答

1

沒有太多去,但...

您使用的是臨時創建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>)跳過空白區域。

如果你可以指定你正在嘗試做什麼,也許我們 可以幫助更多。

+0

好的,但即使我讓這個類的fstream成員,我使用fstream :: open我在同一個地方有同樣的錯誤。 – CppMonster

+0

您的代碼會產生許多編譯錯誤,首先是:錯誤C2446:':':沒有從'std :: filebuf'轉換爲'std :: basic_streambuf <_Elem,_Traits> *' – CppMonster

+1

@CppMonster有一個小錯字,我解決了。 (我使用類似於這個每日的代碼。) –