fopen / fopen_s и запись в файлы - PullRequest
21 голосов
/ 04 апреля 2010

Я использую fopen в C, чтобы записать вывод в текстовый файл. Объявление функции (где ARRAY_SIZE было определено ранее):

void create_out_file(char file_name[],long double *z1){  
  FILE *out;  
  int i;  

  if((out = fopen(file_name, "w+")) == NULL){  
    fprintf(stderr, "***> Open error on output file %s", file_name);  
    exit(-1);  
  }  

  for(i = 0; i < ARRAY_SIZE; i++)  
    fprintf(out, "%.16Le\n", z1[i]);  
  fclose(out);  
}  

Мои вопросы:

  1. При компиляции с MVS2008 я получаю предупреждение: предупреждение C4996: 'fopen': эта функция или переменная может быть небезопасной. Попробуйте вместо этого использовать fopen_s. Я не вижу много информации о fopen_s, чтобы я мог изменить свой код. Какие-либо предложения?

  2. Можно ли поручить fprintf записать числа с требуемой точностью в файл ? Если я использую long double, то я предполагаю, что мои ответы хороши до 15 цифр после запятой. Я прав?

Ответы [ 6 ]

18 голосов
/ 04 апреля 2010

fopen_s - это вариант fopen, который содержит проверку параметров и возвращает код ошибки вместо указателя на случай, если что-то пойдет не так во время открытого процесса. Это более безопасно, чем базовый вариант, потому что учитывает больше граничных условий. Компилятор предупреждает о необходимости его использования, поскольку fopen представляет собой потенциальный вектор использования в вашем приложении.

Вы можете указать цифры точности для семейства функций printf, используя спецификатор %.xg, где x - это цифры точности, которые вы хотите получить при выводе. Точность A long double варьируется от платформы к платформе, но вы можете сделать ставку, если она не менее 16 цифр десятичной точности.

Редактировать: Хотя я не совсем согласен с другими, которые предполагают, что fopen_s - это полная пустая трата времени, это представляет довольно низкий шанс эксплуатации, и это не так широко поддерживается. Однако некоторые другие функции, о которых говорится в C4996, являются гораздо более серьезными уязвимостями, и использование _CRT_SECURE_NO_WARNINGS эквивалентно отключению будильника как для «вы оставили дверь в спальню незапертой», так и для «ядерной бомбы на кухне ».

Пока вы не ограничены использованием «чистого C» для своего проекта (например, для школьного задания или встроенного микроконтроллера), вам будет полезно использовать тот факт, что почти все современные компиляторы C также являются компиляторами C ++ и используйте варианты всех этих функций ввода / вывода для C ++ iostream, чтобы одновременно обеспечить одновременно улучшенную безопасность и .

10 голосов
/ 20 февраля 2013

Я столкнулся с аналогичной проблемой при работе с Visual Studio 2012, но моя проблема расширилась: я создаю программу, в которой я хочу использовать навороты Visual Studio для тестирования и, в конечном итоге, иметь возможность компилировать и запускать ее приложение на моем сервере Linux (я делаю бот)

так вот, что я придумал после некоторого Google, и подумал, что я опубликую его на тот случай, если это может кому-то помочь.

FILE *fp_config;
const char *configfile ;
configfile = "bot.conf";
#ifdef WIN32
    errno_t err;
    if( (err  = fopen_s( &fp_config, configfile, "r" )) !=0 ) {
#else
    if ((fp_config = fopen(configfile, "r")) == NULL) {
#endif
        fprintf(stderr, "Cannot open config file %s!\n", configfile);
    }

это успокоит Visual Studio и не будет жаловаться, а также позволит компилировать тот же код на gcc или любом другом совместимом с c / c ++ стандарте компиляторе

6 голосов
/ 04 апреля 2010
  1. fopen_s и все остальные функции _ являются специфичными для MS «безопасными» вариантами стандартных функций.Если ваш код не должен быть кроссплатформенным, вы можете просто переключиться и порадовать компилятор.В противном случае просто добавьте директиву препроцессора _CRT_SECURE_NO_WARNINGS в настройки вашего проекта, и она перестанет предупреждать вас об этом.

  2. Да, длинная двойка легко подходит для 15 цифр точности;на самом деле, даже обычные пары достаточно хороши для этого (но не более).

4 голосов
/ 27 октября 2013

Переход от fopen к fopen_s отключил возможность открывать файл в блокноте (только для чтения), когда файл открыт и записывается. Вернемся к fopen, и я смогу прочитать, когда моя программа запишет файл.

4 голосов
/ 15 апреля 2011

Другие авторы отмечают, что fopen на самом деле не очень опасен. Если вам не нужно это предупреждение, но вы хотите, чтобы другие предупреждали о реальных уязвимостях, не #define _CRT_SECURE_NO_WARNINGS.

Вместо этого, в следующий раз, когда вы получите предупреждение fopen, нажмите на строку с надписью «см. Объявление« fopen »». Это приведет вас к строке в stdio.h, которая вводит предупреждение. Удалите текст _CRT_INSECURE_DEPRECATE(fopen_s) из этой строки, и вы больше не будете получать предупреждение безопасности при использовании fopen, но оно останется для strcpy, strdup и других, возможно, опасных.

1 голос
/ 04 апреля 2010

Просто определите _CRT_SECURE_NO_WARNINGS, прежде чем включать какой-либо файл, чтобы избавиться от этого предупреждения, и перестаньте верить тому, что MS говорит о fopen

...