2012-11-16 28 views
1

我試圖通過線都要經過一個文件中的行(每行不超過50個字符),由10或-10每個字符移位(加密和解密),並然後打印舊字符串所在的移位字符串。但我得到了一些非常有趣的輸出。重寫線路中的C文件,奇怪輸出

繼承人的代碼:

#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 
+2

「但是我收到了一些非常有趣的輸出「 - 可能更有幫助,更精確... –

+0

您可能不應該使用面向行的'fgets()'和'fputs()',因爲您可以在o中獲得NUL''\ 0''字符輸出數據。使用'fread()'和'fwrite()'。確保你也處理正確的字符數量; fgets()可能不會返回49個字符和一個NUL;該線可能會更短。 –

+0

@MitchWheat很抱歉,希望這對您有所幫助 – agarrow

回答

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;     
    } 

你轉移50個char S,無論多久您在閱讀了,因而大部分的時間,存在在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;

2

嘗試使用GDB調試程序,因爲它加密。

編譯: gcc -g -Wall YOURPROGRAM.cxx

運行GDB: gdb YOURPROGRAM.cxx

設置斷點:

歇在3線:break 3

調試程序:run

你能夠 使用stepnext逐行執行每行代碼,並使用print VARIABLENAME在每個點處輸出變量。這是一個功能強大的程序,對調試非常有幫助。

1

你可能不應該使用面向行的fgets()fputs()因爲你可以得到NUL在加密輸出數據'\0'字符,並在解密輸入數據(和換行會。使用fread()fwrite()。讓當然你也可以處理正確數量的字符; fgets()可能不會返回49個字符和一個NUL;該行可能會更短,並且你不想返回NUL