【问题标题】:Issues with flushing cout after getting file data获取文件数据后刷新 cout 的问题
【发布时间】:2012-04-22 07:43:13
【问题描述】:

我正在尝试编写 rc4 的实现。我正在使用 ifstream 从文件中读取纯文本。我注意到它没有在文件末尾输出,所以我尝试了各种明确清除缓冲区的方法。无论采用哪种方式(使用 endl、附加 \n、调用 cout.flush())我尝试刷新缓冲区,都会出现段错误。作为健全性检查,我用来自网络的示例替换了我的代码,我也单独对其进行了测试。如果我把它放在自己的文件中并编译它,它就可以工作(例如,它打印出文件的内容,没有段错误,并且不需要任何对 flush() 或 endl 的调用),但不是在我的代码中。

这是有问题的代码(在我的代码之外运行良好;它几乎是直接从 cplusplus.com 复制的)

 ifstream is;
 is.open("plain");
 char c;
 while (is.good())     // loop while extraction from file is possible
 {
     c = is.get();       // get character from file
     if (is.good())
         cout << c;
//       cout.flush();
 }
 is.close();           // close file*/

这里是完整的代码:(警告,很多注释掉的代码)

#include <iostream>
#include <fstream>
#include <string.h>
#include <vector>

using namespace std;
static char s[256], k[256];
//static char *i, *j;
void swap(int m, int n, char t[256]){
        char tmp = t[m];
        t[m] = t[n];
        t[n] = tmp;
}

char getByte(){
        static char i(0), j(0);
        i = (i+1)%256;
        j = (j + s[i])%256;
        swap(i, j, s);
        return s[(s[i]+s[j]) % 256];
}

int main(int argc, char ** argv){
        /*string key = argv[1];*/
        if(argc < 4){
                cout << "Usage: \n rc4 keyfile plaintextfile outputfile" << endl;
                return -1;
        }
        string key;
        ifstream keyfile (argv[1]);
        keyfile >> k;
        cout << "Key = " << k << endl;
        keyfile.close();
        /*ifstream plaintextf;
        plaintextf.open(argv[2]);*/

        ofstream ciphertextf (argv[3]);

        for(int q = 0; q < 256; q++){
                s[q] = q;
        }
        int i, j;
        for(int m = 0; m < 256; m++){
                j = (j + s[m] + k[m % sizeof(k)])%256;
                swap(m, j, s);
        }
//      vector<char> bytes(plaintext.begin(), plaintext.end());
//      bytes.push_back('\0');
//      vector<char>::iterator it = bytes.begin();
/*      char pt;
        while(plaintextf.good()){
                pt = plaintextf.get();
                if(plaintextf.good()){
                        cout << pt;

                      ciphertextf <<(char) (pt ^ getByte());
                }

        } */
        ifstream is;
        is.open("plain");
        char c;
         while (is.good())     // loop while extraction from file is possible
         {
            c = is.get();       // get character from file
            if (is.good())
              cout << c;
//              cout.flush();
         }
  is.close();           // close file*/

/*//    plaintextf.close();
        ciphertextf.close();
        keyfile.close();
        */
        return 0;
}

【问题讨论】:

  • 您可能在流中插入了一个原始的'\0' 字符。在插入之前将char 转换为int,看看是否可行。
  • 因为这没有帮助......我在这里有点不知所措。
  • 您是否在调试器中运行过您的程序?它将帮助您查明崩溃的位置,还可以让您检查变量以帮助您找出可能出现的问题。
  • 我在调试器中查看过它。这取决于注释掉的代码,但通常每当我尝试刷新 cout(通过使用 endl 或 flush())或在执行结束时(即使在 return 语句之后),它都会出现段错误。所以在上面的第一段代码中,它在“cout.flush();”上出现了段错误。或者如果我在“cout

标签: c++ file segmentation-fault buffer ifstream


【解决方案1】:

此外,我认为第二次调用 is.good() [ 如 if(is.good()) ] 会阻止文件的最后一个字符被复制。

【讨论】:

  • 我想知道为什么这个例子里面有这个 - 文件好坏没关系,因为我已经使用 get() 将它存储在 c 中?
  • 对 is.get() 的调用可能会失败,这就是他们添加 is.good() 测试的原因。但是,在 EOF 之后 good() 也是错误的。因此,在正常、健康的操作中,good() 将仅因为到达 EOF 而对最后一个字符返回 false。最好用 fail() 替换第二个 good() 测试,因为 fail() 不受 EOF 影响。
  • 感谢您的解释。这似乎与我的问题无关,但是一旦我弄清楚了这个流的废话,它可能会有所帮助。
  • 密钥长度是多少? 256 个字符还是 255 个?您是否需要向 char k[256] 添加一个额外的字节来保存由 operator>> 添加的 NULL ?在任何情况下,文件的构造肯定会导致该缓冲区被写入超出其边界。也许您需要使用二进制读取函数而不是文本提取运算符,或者使用宽度修饰符。
猜你喜欢
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多