Как перейти с fopen на fopen_s

Visual Studio жалуется на fopen. Я не могу найти правильный синтаксис для его изменения. У меня есть:

FILE *filepoint = (fopen(fileName, "r"));

to

FILE *filepoint = (fopen_s(&,fileName, "r"));

Какова остальная часть первого параметра?


person beatleman    schedule 24.02.2015    source источник
comment
fopen_s документирован в MSDN. Предполагается, что первый параметр должен быть FILE**, а возвращаемое значение — errno_t.   -  person Michael    schedule 24.02.2015
comment
Google MSDN fopen_s   -  person pmg    schedule 24.02.2015
comment
Разве F1 больше не работает в Visual Studio?   -  person molbdnilo    schedule 24.02.2015
comment
Я бы просто установил настройки компилятора, чтобы заткнуть предупреждающее сообщение.   -  person Jive Dadson    schedule 17.01.2018


Ответы (1)


fopen_s — это "безопасный" вариант fopen с несколькими дополнительными параметрами для строки режима и другим методом возврата указателя потока и кода ошибки. Он был изобретен Microsoft и вошел в стандарт C: он задокументирован в приложении K.3.5.2.2 самого последнего проекта стандарта C11. Конечно, это полностью задокументировано в интерактивной справке Microsoft. Кажется, вы не понимаете концепцию передачи указателя на выходную переменную в C. В вашем примере вы должны передать адрес filepoint в качестве первого аргумента:

errno_t err = fopen_s(&filepoint, fileName, "r");

Вот полный пример:

#include <errno.h>
#include <stdio.h>
#include <string.h>
...
FILE *filepoint;
errno_t err;

if ((err = fopen_s(&filepoint, fileName, "r")) != 0) {
    // File could not be opened. filepoint was set to NULL
    // error code is returned in err.
    // error message can be retrieved with strerror(err);
    fprintf(stderr, "cannot open file '%s': %s\n",
            fileName, strerror(err));
    // If your environment insists on using so called secure
    // functions, use this instead:
    char buf[strerrorlen_s(err) + 1];
    strerror_s(buf, sizeof buf, err);
    fprintf_s(stderr, "cannot open file '%s': %s\n",
              fileName, buf);
} else {
    // File was opened, filepoint can be used to read the stream.
}

Поддержка Microsoft для C99 является неуклюжей и неполной. Visual Studio выдает предупреждения для допустимого кода, заставляя использовать стандартные, но необязательные расширения, но в данном конкретном случае, похоже, не поддерживает strerrorlen_s. Дополнительные сведения см. в статье отсутствует функция C11 strerrorlen_s в MSVC 2017. .

person chqrlie    schedule 24.02.2015
comment
У strerror аналогичная проблема с fopen. Подумайте о пересмотре, чтобы показать использование strerror_s для +1 от меня? - person Assimilater; 15.04.2016
comment
@Assimilater: нет реальной проблемы с fopen. Visual Studio может выдать предупреждение, предлагая пользователям писать менее переносимый код с помощью fopen_s(). Добавленная семантика в fopen_s, касающаяся разрешений по умолчанию и монопольного режима, лучше всего решать с помощью fdopen, когда она доступна. strerror_s требует, чтобы пользователь предоставил буфер, длина которого должна быть сначала вычислена путем вызова strerrorlen_s(err). Головная боль вряд ли стоит того. - person chqrlie; 16.04.2016
comment
@Assimilater: Тем не менее, я отредактировал ответ и предоставил код для обоих подходов. - person chqrlie; 16.04.2016
comment
Я имел в виду, что, когда я использовал strerror(err), я получил то же предупреждение от Visual Studio (что помешало мне скомпилировать), что и с fopen. :/ - person Assimilater; 10.05.2016
comment
Я не понизил голос, но он жалуется на то, что strerrorlen_s - неизвестный идентификатор. использование по сравнению с 2013 годом - person nurp; 24.11.2017
comment
@nurp: поддержка Microsoft C99 неуклюжа и неполна. VS выдает предупреждения для действительного кода, заставляя использовать необязательные стандартные расширения, но в этом конкретном случае, похоже, не поддерживает strerrorlen_s. См. stackoverflow. com/questions/44430141/ для получения дополнительной информации. - person chqrlie; 25.11.2017