Как напечатать 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 переназначается позже, что может привести к утечке памяти.

Другие вопросы по тегам