2017-04-22 31 views
2

我無法使用open()函數正確打開/創建文件,所以我認爲使用errno消息將幫助我找出原因。但是我不知道如何設置if(),所以它會打印出錯誤信息。 我知道這樣的代碼應該工作:如何在保存函數值的同時打印errno?

if(open(handle,O_RDWR | O_CREAT) == -1){ 
     printf("%s\n",strerror(errno)); 
} 

但如果我想保存從open()來我的變量的值,如果是-1,那麼打印錯誤呢?我不想爲此調用open()兩次,如果沒有問題,我不知道如何分配它,以及如果沒有,則如何打印錯誤。

#include <stdio.h> 
    #include <stdlib.h> 
    #include <fcntl.h> 
    #include <ctype.h> 
    #include <sys/types.h> 
    #include <sys/stat.h> 
    #include <string.h> 
    #include <errno.h> 


    int main(int argc, char **argv){ 
     int handle,i,help; 
     int *array = malloc(5*sizeof(int)); 
     float *red = malloc(5*sizeof(int)); 

     array[0]=5; 
     array[1]=4; 
     array[2]=3; 
     array[3]=2; 
     array[4]=1; 

     handle = open(argv[1], O_RDWR | O_CREAT); 
     if(handle == -1){ 
      printf("%s\n",strerror(errno)); 
     } 

     printf("handle 1 %d\n",handle); 
     write(handle,array,20); 
     close(handle); 

     handle = open(argv[1], O_RDONLY); 
     lseek(handle,0,SEEK_SET); 
     printf("handle %d\n",handle); 
     help=read(handle,&red,20); 
     printf("pomoc %d\n",help); 
     for(i=0; i<5; i++){ 
      printf("%d\n",(int)red[i]); 
     } 
     close(handle); 
     return 0; 
    } 
+0

這是我的「嘗試」代碼,因爲我不確定read()函數是如何工作的,所以我想試試如果我可以在那裏拋出任何類型的指針並讀取任意數量的字節,並且它可以工作,但是我甚至無法通過開幕式。 – ligazetom

+0

請注意,在報告錯誤之後,您不應繼續處理,因爲如果處理已打開。錯誤應該在標準錯誤流上報告,而不是在標準輸出上報告。 –

回答

0

它看起來像你做得很對;只需將open()的返回值保存到一個變量中,然後將其與-1進行比較。精細。

注意,這是破:

float *red = malloc(5*sizeof(int)); 

,因爲誰也不能保證一個float是大小爲int一樣的,這是錯誤的,非常混亂。最好不要在malloc()中重複該類型,因爲這可能會導致引入此錯誤。相反,這樣做:

float * const red = malloc(5 * sizeof *red); 

這使用sizeof *red計算sizeof (float),同時確保該類型是在你的程序中的實際指針。還要注意使用const來防止red在稍後重新分配,這可能會造成內存泄漏。

+0

我只是不確定,因爲當我這樣做時,突然處理的方式不是-1而是0,它不知道要打印什麼。關於分配我知道它不能正常使用我說過,我只是試着用低級函數可以做什麼,但是既然你把它挑出來了,那麼我可以問一下怎麼做呢?我必須寫一個字節的無符號字符,然後隨機數的浮點數,全都是二進制。我應該如何將它們讀回到內存中? – ligazetom

+0

@ligazetom關於如何編碼/序列化數據,這是一個非常不同的問題,並在對這個問題的評論中回答這個問題違背了這個網站應該如何工作。請發佈相關問題或搜索,我知道這已經出現了很多次。 – unwind

1

正確的方式做,這就是:

if((handle=open(argv[1], O_RDWR|O_CREAT, 0666)) == -1){ 

注意,pmode參數需要O_CREAT

+0

那麼這些模式是什麼?我已經看到更多關於它的一些討論,但到目前爲止我還沒有看到任何有關這方面的內容。我在Linux上的btw。 – ligazetom

+0

'_S_IREAD'和'_S_IWRITE'是非標準的。 「open」的第三個參數應該總是「0666」;最重要的例外是包含_secrets_的文件,使用'0600'。 – zwol

+0

'0666',啊,是的,unix。我忘了。謝謝Zwol。 –

1

的問題不是分配給一個變量,它是你調用open方式:

handle = open(argv[1], O_RDWR|O_CREAT); // wrong number of arguments 
if (handle == -1) { 
    printf("%s\n",strerror(errno)); 
} 

當您使用O_CREAT,你必須給open 參數。如果你不這樣做,行爲是不確定的。 由於意外,當您在if中調用open時,出現− 1錯誤返回,並且在將其分配給變量時出現非負的返回值。

除非您有其他的具體原因,否則open的第三個參數應該是幻數0666。 (最常見的具體原因是你正在創建一個文件,該文件將保存祕密信息;然後你使用0600。)(前導零是必需的。)是符號常量,可用於第三個參數爲open,但是,一旦您知道數字「模式」的含義,符號常量實際上更難以閱讀。Here is a detailed explanation of "modes" in both symbolic and numeric forms.

順便說一下,當一個系統調用失敗,你應該總是打印strerror(errno)有問題的文件的名稱(如果有的話):

handle = open(argv[1], O_RDWR|O_CREAT, 0666); 
if (handle == -1) { 
    printf("%s: %s\n", argv[1], strerror(errno)); 
    exit(1); 
} 

你應該想想你是否應該使用O_EXCLO_TRUNC

+1

或者考慮'O_TRUNC',如果不使用'O_EXCL'? –

相關問題