FILE *fp2

Feb 22, 2019 at 1:57pm
Can some one tell me what exactly is following code doing in C, and what is its alternative in C++.

1
2
3
4
FILE *fp2;
fopen_s(&fp2, "lid driven cavity(%dx%d).plt", "w");
fprintf(fp2, "VARIABLES=x,y,u,v,p\n");
fprintf(fp2, "ZONE I=%d, J=%d, F=BLOCK, VARLOCATION=( 3,4,5]=CELLCENTERED)\n\n", Nx + 1, Ny + 1);
Feb 22, 2019 at 2:49pm
Opens a file called "lid driven cavity(%dx%d).plt" (open for writing, without appending), and writes the next two lines to it.

Note on line 4, the first %d is replaced by the value of Nx+1, and the second %d is replaced by the value Ny + 1.

The issue I see with your code is that unlike line 4, line 2 uses fopen_s, which doesn't expect a formatted string. This means that the file name it expects literally contains "%dx%d", not e.g. "10x20".

In C++, something like
1
2
3
4
5
6
7
8
9
10
11
12
13
// Example program
#include <iostream>
#include <string>
#include <fstream>

int main()
{
    int Nx = 10;
    int Ny = 20;
    std::ofstream f2("lid driven cavity(%dx%d).plt"); // this line is probably an error
    f2 << "VARIABLES=x,y,u,v,p\n";
    f2 << "ZONE I=" << Nx + 1 << ", J=" << Ny + 1 << ", F=BLOCK, VARLOCATION=( 3,4,5]=CELLCENTERED)\n\n";
}


If you want a proper filename, I'd do something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Example program
#include <iostream>
#include <string>
#include <fstream>

int main()
{
    int a = 5;
    int b = 6;
    std::string filename = "lid driven cavity(" + std::to_string(a) + "x" + std::to_string(b) + ").plt";
    
    int Nx = 10;
    int Ny = 20;
    std::ofstream f2(filename);
    f2 << "VARIABLES=x,y,u,v,p\n";
    f2 << "ZONE I=" << Nx + 1 << ", J=" << Ny + 1 << ", F=BLOCK, VARLOCATION=( 3,4,5]=CELLCENTERED)\n\n";
}


Someone people that come from C don't like how verbosely the C++ stream's << operators work. You could write your own utility functions to make it look more like C.
Last edited on Feb 22, 2019 at 2:56pm
Feb 22, 2019 at 4:55pm
If you want to use the C style, use the C functions that are right there and fully functional in the c++. They work just fine. Wrapping up C++ style to look like C is going to add a layer of inefficiency and something else to debug and maintain. If you want both worlds, c++ error handling and such, then you would have to roll your own, but it would still add bloat just to change the code cosmetically, a questionable design pattern.
Feb 22, 2019 at 7:41pm
Perhaps you just didn't show it, but you're leaking the file descriptor in your original post. Add fclose(fp2) sometime after the last write to close it.
Feb 23, 2019 at 12:56am
@jonnin,
I would be happy to use the C style, but my compiler VISUAL STUDIO COMMUNITY considers fprintf and fopen as an error. Do I need to change settings of my compiler to run such codes?
Can you tell me the function of pointer in this line
 
 FILE *fp2
Last edited on Feb 23, 2019 at 1:00am
Feb 23, 2019 at 3:33am
probably. I don't recall … do they still have that managed code crap? If so, turn that off for your project; it blocks some perfectly legal code for no reason.

should just work... what error message?

that isn't a function pointer, its a file pointer. literally -- its a pointer to a construct that interacts with files, and its type is also FILE. Its just how you talk to files in C. Forget that its a pointer (you won't new, delete, [], *access, access->thing, or any of the usual pointer stuff here).

Microsoft has also been obsessed with renaming the core C and a few other functions. It may be trying to force you to use fprintf_s() or something like that which it thinks is more secure. This is nonstandard bs from M$, and I don't know how to turn it off in your version, but you can make it stop that with a clicky somewhere. It should just be throwing nonsense warnings, but some settings may make that an error.
Last edited on Feb 23, 2019 at 3:39am
Feb 23, 2019 at 5:33pm
To get the c functions be sure you have :
1
2
3
4
5
#include <cstdio>
using std::fprintf;
using std::fopen;
using std::fclose;
// etc, or do using namespace std;, but that's the lazy way out. 

Feb 23, 2019 at 6:37pm
Feb 24, 2019 at 3:15am
The error I am getting is shown in the figure
https://imgur.com/a/V67kLZs
Last edited on Feb 24, 2019 at 2:30pm
Feb 24, 2019 at 2:14pm
For each of those errors, the problem is the argument to fclose() not fclose() itself. For example, the first one says "Argument of type "FILE**" is incompatible with parameter of type "FILE *". That says that you're passing a FILE** (pointer to pointer to FILE), but fclose() expects you to pass a FILE* (pointer to FILE). It sounds like you declared fp2 as FILE **fp2 instead of FILE *fp2.

Just below that at line 317 you're calling fprintf(&fp3, ...) where fp3 is a FILE *. Just pass fp3 instead.

In general, when using the stdio functions, you declare a variable of type FILE * and the functions return a value of that type, or accept it as a parameter:

1
2
3
FILE *fp = fopen("somefile", "w")
fprintf(fp, "blah blah");
fclose(fp);
Topic archived. No new replies allowed.