自己從手寫cp,記錄
阿新 • • 發佈:2018-12-21
#include <stdio.h> #include <fcntl.h> #define BUF_SIZ 100 /* logic:寫一個cp,要求檔案中的空格不能少 */ /* //fgets char *fgets(char *buf, int bufsize, FILE *stream); 首先他不能直接操作 fd, 只能放數組裡,第三個引數型別是 FILE* fprint 是格式化輸出 //這不就是fd版的 fgets ssize_t read [1] (int fd, void *buf, size_t count); 出錯: 時間往往浪費在簡單的事情上,養成一個好習慣,往往比學習複雜的東西更有用!!!另外還是要多嘗試 O_TRUNC這個東西會清空原來的檔案內容(地基不穩) open write這種函式返回的判斷條件設為 小於0 */ int main(int ac, char * av[]) { int fd,fd1 = -1; if(ac != 3) { printf("cp need two param\n"); return 1; } if((fd = open(av[1], O_RDONLY)) <0){ //這個許可權開始只寫,返回值不是-1,所以一直沒有發現,剛開始好順手寫了第三個引數,只有在該檔案本身許可權允許,才不會報錯 //耽誤了我好長時間 printf("open source file fail \n");return 1; } fd1 = open(av[2], O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH | S_IWOTH); if (fd1 <0) { printf("open object fail \n"); return 1; } ssize_t num; char buf[BUF_SIZ]; int i =0; unsigned long holeSize = 0; while((num = read(fd, buf, BUF_SIZ)) > 0) { printf("num %d\n", num); //應該早點列印num,發現上面括號寫的有問題 for (i = 0; i < num; i++) { if (buf[i] == '\0') { holeSize++; } else if (holeSize > 0) { lseek(fd1, holeSize, SEEK_CUR); write(fd1, &buf[i], 1); holeSize = 0; } else { write(fd1, &buf[i], 1); } } } close(fd); close(fd1); }
除了程式裡標註的低階錯誤,讓我深刻認識到動手的重要性,光這個cp花了我兩個小時。fuck
高階錯誤就是實現該功能的邏輯,根本想不到,好嗎
cp,功能從A檔案中讀,儲存到buf中,然後在寫到B檔案中。
拿到這個問題,首先想了一下,用open比fopen好,具體再補充!!(嘻嘻),然後想有沒有兩個fd直接傳內容過去的功能,
沒有。隨後決定用buff做個快取,這樣的話,buf的大小是個問題,這裡涉及一個思維,只能寫個迴圈,一直到'\0',才取資料結束;那麼buf的大小就成了取資料的單位,就不重要了,這裡是100。因為要一個一個字元判斷是不是 '\0',所以要一個個檢驗,所以一次write一個字元。還有一個比較重要的是,要確保不能覆蓋,所以要用lseek,實現append的功能。