2013-08-02 55 views
2

我用C++編寫了代碼,用於加密和解密。第一個代碼在矢量中創建一個輸出,然後使用fwrite將其寫入文件中,第二個代碼使用fread讀取第一個輸出。 這裏是我的代碼片段:Fwrite和Fread for Vector返回分割錯誤

第一代碼:

..... 
string a; 
vector<long long int> c; 

cout << "message to be encrypted = "; 
cin >> a; 
cout << endl; 

cout << "Encrypted message : "; 
for (i=0;i<a.size();i++) 
{ 
    x=(int)a.at(i); 
    cout << x << " "; 
    c.push_back(powerMod(x,e,n)); 
} 

for (i=0;i<c.size();i++) 
{ 
    //cout << char(c.at(i)); 
} 
cout << endl; 

//Write ciphertext c to a file 
FILE * pWrite; 
pWrite = fopen ("ciphertext", "w"); 
fwrite (&c , sizeof(c), 1, pWrite); 
fclose (pWrite); 

輸出是:

message to be encrypted = test 
Encrypted message : 116 101 115 116 

然後第二代碼:

.... 
//Read Ciphertext from ciphertext 
FILE * pRead2; 
pRead2 = fopen ("ciphertext", "r"); 
fread (&c , sizeof(c), 1, pRead2); 
//cout << "ciphertext is " << c << endl; 

// Decryption 
cout << "Decrypted message : "; 
for (i=0;i<c.size();i++) 
{ 
    cout << powerMod(c.at(i),d,n) << " " ; 
} 
cout << endl; 

但它的回報:

Segmentation Fault(Core Dumped) 

我很感激任何幫助,因爲我不知道問題在哪裏,在fwrite或fread中。但我認爲問題出現在第二次,當它試圖讀取密文(這是一個向量)時,因爲如果我擦除這些行,程序運行完美,但是不解密消息。

謝謝。

+0

你有一個核心轉儲文件嗎?如果是這樣,gdb將幫助你 – doctorlove

+0

你不能將一個矢量存儲到這樣的文件。首先,向量包含一個指向其數據的指針,並且該指針的地址在創建向量的過程中才有意義。嘗試保存向量的元素。另外,請看[boost序列化](http://www.boost.org/doc/libs/1_54_0/libs/serialization/doc/index.html)。 – juanchopanza

回答

5

這是因爲你寫了一個指針指向矢量對象實例,而不是實際的矢量數據。使用

fwrite (&c[0], sizeof(vector<long long int>::value_type), c.size(), pWrite); 

還記得sizeof(c)返回矢量對象實例的大小,在載體項目的數量不限。

閱讀向量時,您也有類似的問題。你必須在一個循環中一個接一個地完成它,再次將這些項目推到vector上。


用C++有這樣做,如果你學會使用C++ I/O stream library和一些不錯的standard algorithms和使用iterators的簡單的方法。

要編寫一個向量到一個文件:

std::ofstream os{"ciphertext", std::ios::out}; 

std::copy(std::begin(c), std::end(c), 
      std::ostream_iterator<long long int>(os)); 

,並從文件讀取:

std::ifstream is{"ciphertext", std::ios::in}; 

std::copy(std::istream_iterator<long long int>(is), 
      std::istream_iterator<long long int>(), 
      std::back_inserter(c)); 

實際上,有從文件到載體中讀取甚至簡單方式:

std::ifstream is{"ciphertext", std::ios::in}; 

std::vector<long long int> c(std::istream_iterator<long long int>(is), 
          std::istream_iterator<long long int>()); 

這依賴於std::vector constructor以兩個迭代器作爲參數。


如果你不想使用文本文件,但二進制文件,你不幸手動必須循環和讀/寫數據,即你必須手動做什麼std::copy爲你做。

像這樣寫數據:

std::ofstream os{"ciphertext", std::ios::out | std::ios::binary}; 

for (const auto& value : c) 
    os.write(reinterpret_cast<const char*>(&value), sizeof(value)); 

而且這樣來閱讀:

std::ifstream is{"ciphertext", std::ios::in | std::ios::binary}; 

long long int value: 
while (is.read(reinterpret_cast<char*>(&value), sizeof(value))) 
    c.push_back(value); 

如果沒有C++ 11 range-based for loop(在寫作中使用上面的例子),使用正常的經典迭代for循環:

std::vector<long long int>::const_iterator i; 
for (i = c.begin(); i != c.end(); ++i) 
    os.write(reinterpret_cast<const char*>(&(*i)), sizeof(*i)); 
+0

謝謝,我嘗試了第二種解決方案,並且錯誤是'istream_operator'不是'std'的成員,我使用了Google搜索,並嘗試了包括,但仍然存在錯誤。 – dulipat

+0

@dulipat'istream_iterator' not'istream_operator' :) –

+0

好主,謝謝你糾正我.. :)好吧,我再次運行它,解密部分有問題。 的加密輸出: 加密消息:104 97 104 97 104 97 同時解密的輸出: 解密的消息= -504 你認爲錯誤在解密算法?或者當它試圖讀取文件時,矢量是不正確的構建? 謝謝。 – dulipat