1

我正在尝试逐行浏览文件(每行不超过 50 个字符),将每个字符移动 10 或 -10(加密和解密),然后在旧字符串所在的位置打印移动后的字符串。但我得到了一些非常有趣的输出。

继承人的代码:

#include <stdio.h>
int main(void){
    FILE *fp;
    fp=fopen("tester.csv","r+");
    Encrypt(fp);      // I call decrypt here when I test it.
    fclose(fp);
}

int Encrypt(FILE *fp){
    int offset=10;
    Shift(fp, offset);
}
int Decrypt(FILE *fp){
    int offset= -10;
    Shift(fp, offset);
}
int Shift(FILE *fp, int offset){
    char line[50],tmp[50], character;
    long position;
    int i;
    position = ftell(fp);
    while(fgets(line,50,fp) != NULL){
        for(i=0;i<50;i++){
            character = line[i];
            character = (character+offset)%256;
            tmp[i] = character;                 
        }
        fseek(fp,position,SEEK_SET);
        fputs(tmp, fp);
        position = ftell(fp);
    }
}

所以如果 tester.csv 最初读取

this, is, a, test

运行程序产生

~rs}6*s}6*k6*~o}~
























êñv[    ‰

this, is, a, test
4

3 回答 3

3
fputs(tmp, fp);

fputs写入字节直到终止 0 字节。

while(fgets(line,50,fp) != NULL){
    for(i=0;i<50;i++){
        character = line[i];
        character += offset;
        tmp[i] = character;                 
    }

无论您读入的行有多长,您都会移动 50char秒,因此在大多数情况下,tmp缓冲区中没有 0 字节,因此fputs通常会写入至少 50 个字节,其中一些与该位置的文件中的内容以及缓冲区之外的内容,这会调用未定义的行为并可能导致崩溃。

您应该检查循环中的终止 0 字节,甚至可能在换行处停止也是一个好主意。

while(fgets(line,50,fp) != NULL){
    for(i = 0; i < 50 && line[i] != 0 && line[i] != '\n'; i++){
        character = line[i];
        character += offset;
        tmp[i] = character;                 
    }

注意:循环体会更简单line[i] += offset;

于 2012-11-16T00:50:31.507 回答
2

尝试在加密时使用 GDB 调试您的程序。

编译: gcc -g -Wall YOURPROGRAM.cxx

运行 gdb: gdb YOURPROGRAM.cxx

设置断点:

在第 3 行中断:break 3

调试你的程序:run

step您可以使用和单步执行每一行代码next,并使用 打印每个点的变量print VARIABLENAME。这是一个功能强大的程序,对调试非常有帮助。

于 2012-11-16T00:43:45.227 回答
1

您可能不应该使用面向行的fgets(),因为您可以在加密的输出数据和解密的输入数据中fputs()获得 NUL字符(换行符将是 . 使用和。确保您也处理正确数量的字符;可能不会返回 49 个字符和 NUL;该行可能会更短,并且您无论如何都不想处理 NUL。'\0'fread()fwrite()fgets()

于 2012-11-16T00:55:12.910 回答