2017-04-22 62 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'? –