1. 程式人生 > >自己從手寫cp,記錄

自己從手寫cp,記錄

#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的功能。