【问题标题】:Failure when retrieving string from the end of a file从文件末尾检索字符串时失败
【发布时间】:2011-04-01 23:18:51
【问题描述】:

我有一个简单的应用程序,它接受文本和密码,生成文本并将其写入文件,然后尝试检索并解密它。在加密之前,会生成“pad”,它是从密码生成的字符串,带有文本的长度。当我尝试检索文本时出现问题,因为无论我如何尝试,我都会不断检索错误的文本,因为它与密码的长度不匹配。

cout << " !!! DEBUG ONLY. CHANGE MAIN CODE BEFORE RELEASE !!!\n";
string text, password, file;
cout << "Please enter the text you would like encrypted: ";
getline(cin, text);
cout << "Please enter the password for creating the cipher: ";
getline(cin, password);
cout << "Please enter the file path: ";
getline(cin, file);
password = GeneratePad(password, text.size());
string separator = "30436f4a57e831406e8c0ef203923fe3ba9d0ac4TB5Mi4b33A";
ofstream mann(file.c_str(), ios::app);
mann << "\n" << separator << CryptText(text, password);
mann.close();
cout << " !!! DEBUG ONLY. CHANGE MAIN CODE BEFORE RELEASE !!!\n";
ifstream frau(file.c_str(), ios::binary);
string foobar;
bool barfoo = false;
string decrypted;
while (!barfoo)
{
    getline(frau, foobar);
    if(foobar.find(separator) != string::npos){
        decrypted += foobar.substr(separator.length() + 1);
        cout << "SUBSTR " << foobar.substr(separator.length() + 1);
        barfoo = true; }    }
while (getline(frau, foobar))
{
    decrypted += foobar;
}
string decrypted2;
cout << "    LEN      " << decrypted.length() << "     !!!!!     " << decrypted << endl;
decrypted2 = CryptText(decrypted, password);
cout << decrypted2 << endl;
system("PAUSE");

看起来不必要的东西纯粹是为了调试(比如输出原始加密文本等)。关于为什么会发生这种情况的任何想法?

【问题讨论】:

  • 为什么要在以二进制形式打开的文件上使用 getline()?
  • 为什么不呢?顺便说一句,我有点新手,所以你可能是对的。
  • 默认情况下它会读到一个换行符。不知道你的秘诀函数在做什么,但你确定你正在写一个换行符,因此读入的行大小相同吗?
  • 是的,忘记添加“\n”是问题之一。感谢您的帮助。

标签: c++ string file encryption


【解决方案1】:

问题 1:您以文本模式打开输出文件,但以二进制模式读取它。

std::ofstream mann(file.c_str(), std::ios::app|std::ios::binary);

问题 2:您的加密数据可能不再是 ASCII 文本。它可能包含特殊字符,如 '\n' 或 ^Z 甚至嵌入的 '\0' 字符。您应该使用未格式化的 i/o,例如 read() 和 write(),而不是 getline() 和

其他 cmets:
不要使用系统(“暂停”);。它的风格很差,使程序不必要地依赖于系统。只需使用常规 C++ i/o 编写暂停消息并等待按下返回即可。

std::cout << "Press return to continue" << std::endl;
std::getline();

我建议不要使用“使用命名空间 std”,而只是在需要时使用 std:: 限定符。它使事情变得更清洁。

【讨论】:

    【解决方案2】:

    我做了以下 2 次修改:

    ofstream mann(file.c_str(), ios::app|ios::binary);
    while (getline(frau, foobar))   
    {   
    decrypted += foobar;
    decrypted += "\n";
    } 
    

    当我打开文件进行阅读时,我还添加了 ios::binary,当我添加到解密的字符串时,我添加了被“getline”删除的“\n”。 现在完美运行。

    【讨论】:

      猜你喜欢
      • 2013-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-19
      相关资源
      最近更新 更多