Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fopen / fopen_s and writing to files

Tags:

I'm using fopen in C to write the output to a text file. The function declaration is (where ARRAY_SIZE has been defined earlier):

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);   }   

My questions:

  1. On compilation with MVS2008 I get the warning: warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. I haven't see much information on fopen_s so that I can change my code. Any suggestions?

  2. Can one instruct fprintf to write numbers at a desired numerical precision to a file? If I'm using long double then I assume that my answers are good till 15 digits after the decimal point. Am I right?

like image 479
yCalleecharan Avatar asked Apr 04 '10 16:04

yCalleecharan


People also ask

What is fopen mode string for writing a text file?

The fopen() function opens the file specified by filename and associates a stream with it. The mode variable is a character string specifying the type of access requested for the file.

What does fopen_s return?

Opens a stream. fopen_s opens the file named by filename and associates a stream to it. fopen returns a pointer used to identify the stream in subsequent operations. The mode string used in calls to fopen is one of the following values: Value.

Can fopen create files?

The fopen function creates the file if it does not exist. r+b or rb+ Open a binary file for both reading and writing. The file must exist.

Will fopen create a file C++?

The fopen() function creates the file if it does not exist. Notes: The fopen() function is not supported for files that are opened with the attributes type=record and ab+, rb+, or wb+ Use the w, w+, wb, w+b, and wb+ parameters with care; data in existing files of the same name will be lost.


1 Answers

fopen_s is a variant of fopen which contains parameter validation and hands back an error code instead of a pointer in case something goes wrong during the open process. It's more secure than the base variant because it accounts for more edge conditions. The compiler is warning you to use it because fopen represents a potential exploitation vector in your application.

You can specify digits of precision to the printf family of functions by using the specifier %.xg, where x is the digits of precision you want in the output. A long double varies in precision from platform to platform, but you can generally bet on it being at least 16 digits of decimal precision.

Edit: While I'm not entirely on board with the others who are suggesting that fopen_s is a complete waste of time, it does represent a pretty low chance of exploitation and it isn't widely supported. Some of the other functions warned about under C4996 are much more serious vulnerabilities, however, and using _CRT_SECURE_NO_WARNINGS is the equivalent of turning off the alarm for both "you left your bedroom door unlocked" and "you left a nuclear bomb in the kitchen".

As long as you aren't restricted to using "pure C" for your project (e.g. for a school assignment or an embedded microcontroller), you would do well to exploit the fact that almost all modern C compilers are also C++ compilers and use the C++ iostream variants of all of these I/O functions in order to get both improved security and compatibility at the same time.

like image 94
Dan Story Avatar answered Oct 09 '22 12:10

Dan Story