Как напечатать errno при сохранении значения из функции?
Я не могу правильно открыть / создать файл с помощью функции open(), поэтому я подумал, что использование сообщений errno поможет мне выяснить причину. Однако я не знаю, как установить if (), поэтому он выводит мне ошибку. Я знаю, код, как это должно работать:
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;
}
3 ответа
Проблема не в присвоении переменной, а в том, как вы вызываете open
:
handle = open(argv[1], O_RDWR|O_CREAT); // wrong number of arguments
if (handle == -1) {
printf("%s\n",strerror(errno));
}
Когда вы используете O_CREAT
, вы должны дать open
три аргумента. Если вы этого не сделаете, поведение не определено. Случайно вы получили ошибку -1, когда у вас был open
позвоните внутрь if
и неотрицательное возвращаемое значение при назначении его переменной.
Если у вас нет конкретной причины поступить иначе, третий аргумент open
должно быть магическое число 0666
, (Наиболее распространенная конкретная причина, чтобы сделать иначе - это то, что вы создаете файл, который будет содержать секретную информацию; затем вы используете 0600
.) (Требуется начальный ноль.) Существуют символические константы, которые можно использовать для третьего аргумента open
но как только вы узнаете, что означают числовые "моды", символические константы на самом деле сложнее для чтения. Вот подробное объяснение "мод" как в символической, так и в числовой форме.
Кстати, при сбое системного вызова вы всегда должны печатать оба 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_EXCL
или же O_TRUNC
,
Правильный способ сделать это:
if((handle=open(argv[1], O_RDWR|O_CREAT, 0666)) == -1){
Обратите внимание, что pmode
аргумент необходим для O_CREAT
,
Похоже, вы делаете это правильно; просто сохраните возвращаемое значение open()
к переменной, затем сравните это с -1. Хорошо.
Обратите внимание, что это не работает:
float *red = malloc(5*sizeof(int));
так как нет гарантии, что float
такой же размер как int
это неправильно и очень запутанно. Лучше не повторять тип в malloc()
так как это рискует внести эту ошибку. Вместо этого сделайте:
float * const red = malloc(5 * sizeof *red);
Это использует sizeof *red
вычислить sizeof (float)
, при этом удостоверившись, что тип соответствует фактическому указателю в вашей программе. Также обратите внимание на использование const
защищать от red
переназначается позже, что может привести к утечке памяти.