2010-09-05 80 views
0

我已經編寫了代碼,理想情況下應該從一個文檔中獲取數據,對其進行加密並將其保存在另一個文檔中。與文件描述符代碼中的問題。 C(Linux)

但是當我嘗試執行代碼時,它不會將加密數據放入新文件中。它只是留下了空白。有人請發現代碼中缺少的內容。我試過但我無法弄清楚。

我認爲讀/寫功能有問題,或者我錯誤地實現了do-while循環。

#include <stdio.h> 
#include <stdlib.h> 
#include <termios.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 
#include <unistd.h> 


int main (int argc, char* argv[]) 
{ 
    int fdin,fdout,n,i,fd; 
    char* buf; 
    struct stat fs; 

    if(argc<3) 
     printf("USAGE: %s source-file target-file.\n",argv[0]); 

    fdin=open(argv[1], O_RDONLY); 
    if(fdin==-1) 
     printf("ERROR: Cannot open %s.\n",argv[1]); 

    fdout=open(argv[2], O_WRONLY | O_CREAT | O_EXCL, 0644); 
    if(fdout==-1) 
     printf("ERROR: %s already exists.\n",argv[2]); 

    fstat(fd, &fs); 
    n= fs.st_size; 
    buf=malloc(n); 

    do 
    { 
     n=read(fd, buf, 10); 

     for(i=0;i<n;i++) 
      buf[i] ^= '#'; 

     write(fd, buf, n); 
    } while(n==10); 

    close(fdin); 
    close(fdout); 
} 
+1

都讀取,並使用相同的文件描述符寫?沒有人使用fd {in,out}? – racetrack 2010-09-05 18:40:25

回答

2
// Here... 
fstat(fd, &fs); 

// And here... 
n=read(fd, buf, 10); 

for(i=0;i<n;i++) 
    buf[i] ^= '#'; 

write(fd, buf, n); 

你讀取和寫入fd而不是fdinfdout。確保啓用編譯器將發出的所有警告(例如,使用gcc -Wall -Wextra -pedantic)。如果你願意,它會警告你使用未初始化的變量。

此外,如果您檢查了fstat()read()write()的返回碼,那麼您很可能會因使用無效的文件描述符而發生錯誤。它們很可能與EINVAL(無效參數)錯誤錯誤。

fstat(fd, &fs); 
n= fs.st_size; 
buf=malloc(n); 

因爲我們在這裏:分配足夠的內存來保存整個文件是不必要的。在循環中,您一次只能讀取10個字節,因此您只需要一個10字節的緩衝區。你可以完全跳過fstat()

// Just allocate 10 bytes. 
buf = malloc(10); 

// Or heck, skip the malloc() too! Change "char *buf" to: 
char buf[10]; 
+0

謝謝.. :)它的工作。我完全瞭解你答案的最後一段。請你用外行語言來闡述。請原諒我,我是一個初學者。 – Pavitar 2010-09-05 18:45:45

+1

@Pavitar添加了解釋我的技術喋喋不休的代碼。這有幫助嗎? :) – 2010-09-05 18:52:22

3

您在fstat中使用fd而不是fdin,讀取和寫入系統調用。 fd是未初始化的變量。

0

所有的說法都是真的,還有一個小費。

您應該使用適合系統硬盤塊的較大緩衝區,通常爲8192. 這會顯着增加您的程序速度,因爲您將對磁盤的訪問次數減少800倍。如您所知,訪問磁盤在時間上非常昂貴。

另一個選擇是使用stdio函數fread,fwrite等,它已經處理緩衝,仍然會有函數調用開銷。 Roni