Как использовать assert с fopen в C? - PullRequest
0 голосов
/ 01 мая

У меня есть задача, и мне нужен ваш совет

Я запускаю свою программу с аргументами, например

./program.x input.txt output.txt

Так что в своей программе я проверяю, правильно ли я использую аргументы

    if (argc != 3) {                                
    printf("Wrong arguments number\n");
    printf("I should run this way:\n");
    printf("%s source result\n",argv[0]);
    exit(1);
    }

    if( (wz= fopen(argv[1],"r")) == NULL) {
        printf("Open error %s\n", argv[1]);
        exit(1);
    }

    if( (wc= fopen(argv[2],"w")) == NULL) {
        printf("Open error %s\n", argv[2]);
        exit(2);
    }

Я также использую assert, чтобы проверить, что файл в порядке, нам сказали, что мы тоже должны использовать assert

    assert((wz = fopen(argv[1] ,"r")));
    assert((wc = fopen(argv[2] ,"w")));

Но я не знаю, должен ли я сначала поставить assert или сначала проверить количество аргументов ?

    if (argc != 3) {                                
    printf("Wrong arguments number\n");
    printf("I should run this way:\n");
    printf("%s source result\n",argv[0]);
    exit(1);
    }

    if( (wz= fopen(argv[1],"r")) == NULL) {
        printf("Open error %s\n", argv[1]);
        exit(1);
    }

    if( (wc= fopen(argv[2],"w")) == NULL) {
        printf("Open error %s\n", argv[2]);
        exit(2);
    }
    assert((wz = fopen(argv[1] ,"r")));
    assert((wc = fopen(argv[2] ,"w")));

или

    if (argc != 3) {                                
    printf("Wrong arguments number\n");
    printf("I should run this way:\n");
    printf("%s source result\n",argv[0]);
    exit(1);
    }

    if( (wz= fopen(argv[1],"r")) == NULL) {
        printf("Open error %s\n", argv[1]);
        exit(1);
    }

    if( (wc= fopen(argv[2],"w")) == NULL) {
        printf("Open error %s\n", argv[2]);
        exit(2);
    }
    assert((wz = fopen(argv[1] ,"r")));
    assert((wc = fopen(argv[2] ,"w")));
    if (argc != 3) {                                
    printf("Wrong arguments number\n");
    printf("I should run this way:\n");
    printf("%s source result\n",argv[0]);
    exit(1);
    }

    if( (wz= fopen(argv[1],"r")) == NULL) {
        printf("Open error %s\n", argv[1]);
        exit(1);
    }

    if( (wc= fopen(argv[2],"w")) == NULL) {
        printf("Open error %s\n", argv[2]);
        exit(2);
    }

1 Ответ

1 голос
/ 01 мая

assert(expression) - это макрос, определяемый как #include <assert.h>.

Если макрос NDEBUG определен перед строкой #include <assert.h>, то вызов макроса assert(expression) расширяется до выражения void ((void)0) , В противном случае он запишет сообщение об ошибке в стандартный поток ошибок и вызовет abort().

Поскольку assert(expression) может не генерировать никакого кода, его не следует вызывать, если expression имеет какие-либо побочные эффекты. Одним из примеров побочного эффекта является присвоение значения переменной (или другому lvalue). Другим примером побочного эффекта является открытие файла. Звонок assert((wz = fopen(argv[1] ,"r"))); делает обе эти вещи. Правильный способ использования assert в этом случае - выполнить операцию до вызова assert и использовать только assert для проверки результата. Например:

wz = fopen(argv[1], "r");
assert(wz != NULL);

Выражение wz != NULL не имеет побочных эффектов (при условии, что wz не был объявлен с квалификатором типа volatile), поэтому безопасно.


OP использует assert как часть упражнения. Следует отметить, что assert обычно используется только для проверки того, что не должно завершиться сбоем, а сообщение, которое он записывает в стандартный поток ошибок, предназначено для того, чтобы помочь разработчику обнаружить ошибки в коде. Тем не менее, вызов fopen для аргумента командной строки вполне может привести к сбою и обычно должен обрабатываться так, чтобы это было полезно пользователю программы, а не разработчику.

...