fscanf - how read file in c
fopen/fopen_s y escritura a archivos (6)
Estoy usando fopen en C para escribir la salida en un archivo de texto. La declaración de la función es (donde ARRAY_SIZE
se ha definido anteriormente):
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);
}
Mis preguntas:
En la compilación con MVS2008, recibo la advertencia: advertencia C4996: ''fopen'': esta función o variable puede no ser segura. Considera usar fopen_s en su lugar. No he visto mucha información en
fopen_s
para poder cambiar mi código. ¿Alguna sugerencia?¿Se puede
fprintf
afprintf
que escriba números con una precisión numérica deseada en un archivo ? Si estoy usando ellong double
, asumo que mis respuestas son buenas hasta 15 dígitos después del punto decimal. Estoy en lo cierto
fopen_s
y todas las demás funciones _s son variantes "seguras" de funciones estándar específicas de MS. Si su código no necesita ser multiplataforma, simplemente puede cambiar y hacer feliz al compilador. De lo contrario, solo agregue la_CRT_SECURE_NO_WARNINGS
preprocesador_CRT_SECURE_NO_WARNINGS
en la configuración de su proyecto y dejará de advertirle al respecto.Sí, el doble largo es fácilmente bueno para 15 dígitos de precisión; en realidad, incluso los dobles regulares son lo suficientemente buenos para eso (pero no más).
Me encontré con un problema similar al trabajar con Visual Studio 2012, pero donde mi problema se expandió fue al crear un programa que quiero usar las campanas y los silbidos de Visual Studio para probar y, finalmente, poder compilar y ejecutar la misma aplicación en mi Servidor Linux (estoy haciendo un bot)
así que esto es lo que se me ocurrió después de algo de Google y pensé que lo publicaría en caso de que pudiera ayudar a alguien más.
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);
}
Esto apaciguará a Visual Studio y no se quejará, y también permitirá que se compile el mismo código en gcc o en cualquier otro compilador compatible con c / c ++ de estándares.
Otros carteles han señalado que fopen no es realmente muy inseguro. Si no desea esta advertencia, pero sí desea las otras que advierten sobre vulnerabilidades reales, no #define _CRT_SECURE_NO_WARNINGS
.
En cambio, la próxima vez que reciba la advertencia de fopen, haga clic en la línea que dice "ver declaración de ''fopen''". Esto lo llevará a la línea en stdio.h que está inyectando la advertencia. Elimine el texto _CRT_INSECURE_DEPRECATE(fopen_s)
de esa línea, y ya no recibirá la advertencia de seguridad cuando use fopen, pero permanecerá para strcpy, strdup y aquellos otros posiblemente peligrosos.
Pasar de fopen a fopen_s deshabilitó la capacidad de abrir un archivo en el bloc de notas (solo lectura) mientras el archivo está abierto y se está escribiendo. Cambiando de nuevo a Fopen, puedo leer mientras mi programa escribe el archivo.
Simplemente defina _CRT_SECURE_NO_WARNINGS
antes de incluir cualquier archivo para deshacerse de estas advertencias, y deje de creer lo que MS dice sobre fopen
fopen_s
es una variante de fopen
que contiene la validación de parámetros y devuelve un código de error en lugar de un puntero en caso de que algo salga mal durante el proceso de apertura. Es más seguro que la variante base porque representa más condiciones de borde. El compilador le advierte que lo use porque fopen
representa un posible vector de explotación en su aplicación.
Puede especificar dígitos de precisión para la familia de funciones printf
usando el especificador %.xg
, donde x es el dígito de precisión que desea en la salida. Un long double
varía en precisión de una plataforma a otra, pero generalmente puede apostar a que tenga al menos 16 dígitos de precisión decimal.
Edit: Si bien no estoy completamente a bordo con los otros que sugieren que fopen_s
es una completa pérdida de tiempo, representa una probabilidad bastante baja de explotación y no está ampliamente respaldado. Sin embargo, algunas de las otras funciones sobre las que se advierte en C4996 son vulnerabilidades mucho más graves, y usar _CRT_SECURE_NO_WARNINGS
es el equivalente a apagar la alarma para "dejaste la puerta de tu habitación sin llave" y "dejaste una bomba nuclear en la cocina".
Siempre y cuando no esté limitado a usar "C pura" para su proyecto (por ejemplo, para una tarea escolar o un microcontrolador incorporado), haría bien en explotar el hecho de que casi todos los compiladores de C modernos también son compiladores de C ++ y usa el C ++ iostream
variantes de todas estas funciones de E / S para obtener seguridad y compatibilidad mejoradas al mismo tiempo.