Подтвердить что ты не робот

Fopen/fopen_s и запись в файлы

Я использую 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);  
}  

Мои вопросы:

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Я столкнулся с аналогичной проблемой, связанной с 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/С++, совместимом с другими стандартами

Ответ 3

  • fopen_s, а все остальные _s - это "безопасные" варианты стандартных функций. Если ваш код не должен быть кросс-платформенным, вы можете просто переключиться и сделать компилятор счастливым. В противном случае просто добавьте директиву _CRT_SECURE_NO_WARNINGS pre-processor в свои настройки проекта, и она перестанет предупреждать вас об этом.

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

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