equivalent of c++ freopen in c, as safe as possible - c++

I am used to C++ in competitive programming. Below is my C++ temaplate:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int a;
cin >> a;
cout << a * 4 << " " << a * a;
}
I want a safe equivalent in C, I tried to find it on my own, but found many versions.
I have found the following equivalent, is that the one you'd recommend?
#include <stdio.h>
int main() {
FILE* inp = freopen("input.txt", "r", stdin);
FILE* out = freopen("output.txt", "w", stdout);
int a;
scanf("%d", &a);
printf("%d %d", a*4, a*a);
fclose(stdout);
}
Is this safe and optimal?

The second code snippet is equivalent to the first one, except that you ignore the return value of freopen in the former, and save it in the later.
If the file is successfully reopened, the function returns the pointer
passed as parameter "stream", which can be used to identify the
reopened stream. Otherwise, a null pointer is returned. On most
library implementations, the errno variable is also set to a
system-specific error code on failure.
I'd say the second one might be
more secure, as freopen returns NULL on failure, and inp and
oup can be used to check for an error.
If a new filename is specified, the function first attempts to close
any file already associated with stream (third parameter) and
disassociates it. Then, independently of whether that stream was
successfuly closed or not, freopen opens the file specified by
filename and associates it with the stream just as fopen would do
using the specified mode.
independently of whether that stream was successfuly closed or not suggests that it could remain open, or be in some error state. But failure to close the original stream shall be ignored.

Is this safe and optimal?
Neither is safe as the return values of freopen() and scanf() are not checked.
Suggest add error checking:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE* inp = freopen("input.txt", "r", stdin);
if (inp == NULL) {
fprintf(stderr, "Unable to reopen stdin.\n");
return EXIT_FAILURE;
}
FILE* out = freopen("output.txt", "w", stdout);
if (out == NULL) {
fclose(inp);
fprintf(stderr, "Unable to reopen stdout.\n");
return EXIT_FAILURE;
}
int a;
if (scanf("%d", &a) != 1) {
fprintf(stderr, "Failed to read an int.\n");
} else {
printf("%d %d", a*4, a*a);
}
fclose(stdin);
fclose(stdout);
}

Related

What is causing my C++ cat function to give a "Bad Address" error when opening two or more files?

I am attempting to write a function that serves the same purpose as the Linux command 'cat'. The program is successfully opening and reading the first file. However, if two or more files are attempted to be opened and read, then I get a "Bad Address" error message upon trying to open the second file.
#include <iomanip>
#include <fstream>
#include <sys/types.h> //open header files
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> // read header file
using namespace std;
int main(int argc, char *argv[])
{
int fd;
ssize_t nr;
// executable was ran without input files typed afterwards
if(argc == 0) {cout << "No files listed as argument" << endl; exit(1);}
for(int i = 1; i < argc; i = i + 1)
{
fd = open(argv[i], O_RDONLY, 0644); //file opening
char *buffer; // for containing the character string locations of files
if(fd == -1) {perror("File Opening Error"); return 2;} //end if
nr = read(fd, buffer, 100); // not quite sure what to type for the byte count?????
buffer[nr] = '\0';
if(nr == -1) {perror("File REading Error"); return 3;} //end if
cout << buffer << endl;
close(fd);
} //end for
return 0;
}```
char *buffer;
This declares a new pointer called buffer. It is not initialized to point to anything. The pointer's value is random garbage, at this time. Immediately afterwards:
nr = read(fd, buffer, 100);
This attempts to read up to 100 bytes into the buffer. However since buffer is not a valid pointer, and this results in undefined behavior. This is the reason for your program failing.
The program is successfully opening and reading the first file
Only by random chance. "Undefined behavior" means anything can happen.
// not quite sure what to type for the byte count?????
That's because there is no valid value by the byte count.
It's simpler to use an actual buffer, instead:
char buffer[256];
Now you can confidently use a count of 255, leaving room for the trailing \0 that gets added to the end of the read data.

Read Multiple Files In C++

I am trying to read two files "ListEmployees01.txt" and "ListEmployees02.table". But the program reads only the "ListEmployees01.txt" file and cout is just from that file.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
int main()
{
freopen("ListEmployees01.txt", "r", stdin);
string s;
while (getline(cin, s))
cout << s<<endl;
fclose(stdin);
freopen("ListEmployees02.table", "r", stdin);
while (getline(cin, s))
cout << s<<endl;
}
You can use std::ifstream instead of changing std::cin's behavior.
I would do the following using fstream
#include <fstream>
void readAndPrint(const char *filename) {
std::ifstream file(filename);
if (file.is_open()) {
std::string line;
while (getline(file, line)) {
printf("%s\n", line.c_str());
}
file.close();
}
}
int main() {
readAndPrint("ListEmployees01.txt");
readAndPrint("ListEmployees02.table");
return 0;
}
If you must use freopen, then have a look at man freopen, or the C++ reference http://www.cplusplus.com/reference/cstdio/freopen .
In your case , in the case of second file you are using the stdin which is already closed by below line , hence it is a dangling pointer after file close
fclose(stdin)
You can use fopen instead of freopen for the second file.
Please check the below paragraph from www.cplusplus.com/reference/cstdio/freopen/
If a new filename is specified, the function first attempts to close
any file already associated with stream (third parameter) and
disassociates it. Then, independently of whether that stream was
successfuly closed or not, freopen opens the file specified by
filename and associates it with the stream just as fopen would do
using the specified mode.

How Can I use the system call write() to output to a file (write to a file)?

So I am learning an operating systems course and right now I am learning how to do system calls. So Basically ,I want to copy an input file openClose.in to a file called openClose.out. So far here is my code
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <sys/types.h> //needed for open
#include <sys/stat.h> //needed for open
#include <fcntl.h> //needed for open
#include <errno.h> //must use for perror
#include <grp.h>
#include <pwd.h>
using namespace std;
int main (int argc, char *argv[])
{
int inFile;
int outFile;
int n_char=0;
char buffer[32];
int fstat(int fildes, struct stat *buf);
struct stat statBuf;
struct group grp;
struct passwd pwd;
int err;
int err2;
if(argc != 3)
{
printf("Usage: openClose <infile> <outfile> \n");
//return 1;
exit(1);
}
inFile=open(argv[1],O_RDONLY);
outFile=open(argv[2],O_RDWR);
if (inFile==-1)
{
printf("");
perror(argv[1]);
exit(1);
}
//Use the read system call to obtain 32 characters from inFile
while( (n_char=read(inFile, buffer, 32))!=0)
{
//Display the characters read
n_char=write(argv[2],buffer,n_char);
}
err = fstat(inFile, &statBuf);
printf("The is the status of %d\n", argv[1]);
printf("File Size \t Owner \t Group ID \t Last Modified \n %d \t \t %d \t %d \t \t %d \n",statBuf.st_size,statBuf.st_uid,stat,statBuf.st_gid,statBuf.st_mtime);
return 0;
}
But I couldn't seem to get it working, for some reason, I don't know why I am not able to see the output file.
I am running my program from the terminal with two arguments like the following
open(executable) inputfile1 inputfile2
Your use of write() is not correct:
n_char=write(argv[2],buffer,n_char);
The first argument should be a file descriptor, so use outFile instead of the file name in argv[2].
By the way, you should take the habit of verifying if your opening succeded, before trying to do any file i/o. You did it well for inFile, do it also for outFile

Get the output of one C program into a variable in another C program

I have 2 C programs.
Say one is program-1.c
int main(){
printf("hello world");
}
Now in 2nd code named program-2.c, I want the output of 1st code into a variable,
so that I can have the output "hello world" into a variable in the 2nd C code.
How can I do this?
You can use the popen function for this:
FILE* proc1 = popen("./program1", "r");
// Usual error handling code goes here
// use the usual FILE* read functions
pclose(proc1);
You will need to run the two programs in two separate processes and then use some sort of IPC mechanism to exchange data between the two processes.
On many operating systems you can get the output from one console program as input to the next, perhaps
program-1 > program-2
you can then read the result from standard input
std::string variable;
std::getline(std::cin, variable);
Sample Code for "Output of one program is input of another program Using Pipes"
#include <unistd.h>
#include <process.h>
/* Pipe the output of program to the input of another. */
int main()
{
int pipe_fds[2];
int stdin_save, stdout_save;
if (pipe(pipe_fds) < 0)
return -1;
/* Duplicate stdin and stdout so we can restore them later. */
stdin_save = dup(STDIN_FILENO);
stdout_save = dup(STDOUT_FILENO);
/* Make the write end of the pipe stdout. */
dup2(pipe_fds[1], STDOUT_FILENO);
/* Run the program. Its output will be written to the pipe. */
spawnl(P_WAIT, "/dev/env/DJDIR/bin/ls.exe", "ls.exe", NULL);
/* Close the write end of the pipe. */
close(pipe_fds[1]);
/* Restore stdout. */
dup2(stdout_save, STDOUT_FILENO);
/* Make the read end of the pipe stdin. */
dup2(pipe_fds[0], STDIN_FILENO);
/* Run another program. Its input will come from the output of the
first program. */
spawnl(P_WAIT, "/dev/env/DJDIR/bin/less.exe", "less.exe", "-E", NULL);
/* Close the read end of the pipe. */
close(pipe_fds[0]);
/* Restore stdin. */
dup2(stdin_save, STDIN_FILENO);
return 0;
}
Cheers....
In the code for the program-2.c you should use int argc and char *argv[] to get the output from program-1.c
So program-2.c should look like this:
void main(int argc, char *argv[])
{
int i;
for( i=0; i<argc; i++ )
{
printf("%s", argv[i]); //Do whatever you want with argv[i]
}
}
Then in the command prompt program-1 > program-2
On windows u can use this example...
#include <iostream>
#include<time.h>
 
using namespace std;
 
int main()
{
int a=34, b=40;
 
while(1)
{
usleep(300000); 
cout << a << " " << b << endl;
}
}
#include<iostream>
 
using namespace std;
 
int main()
{
int a, b;
 
while(1)
{
cin.clear();
 
cin >> a >> b;
 
if (!cin) continue;
 
cout << a << " " << b << endl;
}
}
You have to observe and set the usleep() value to successfully get the input from the output of the other program. Run both programs simultaneously. Enjoy..:)

C++ input and output files

So im writing c++ program, that takes a integer from input file, multiply it with 2 and outputs it on output file. So the code is -
#include <stdio.h>
#include <iostream>
using namespace std;
int main() {
int n;
FILE * inFile;
FILE * outFile;
inFile = fopen ("reiz.in","r");
outFile = fopen ("reiz.out","r+");
fscanf (inFile, "%s", n);
int m = n * 2;
fprintf (outFile, "%n", n);
fclose (inFile);
fclose (outFile);
return 0;
}
But something is wrong. in reiz.in file there is number 2, after running program it should output 4 in reiz.out, but it just shows don't send error. What exactly is wrong with my script?
Best regards,
Y2oK
EDIT 1: Ok now it looks like this -
#include <stdio.h>
#include <iostream>
using namespace std;
int main() {
int n;
FILE * inFile;
FILE * outFile;
inFile = fopen ("reiz.in","r");
outFile = fopen ("reiz.out","r+");
fscanf (inFile, "%d", &n);
int m = n * 2;
fprintf (outFile, "%d", m);
fclose (inFile);
fclose (outFile);
return 0;
}
but still it gives same don't send error when running reiz.exe file, and it doesn't write anything on output file
I'm now a little bit confused, and don't know who to chose as best answer, so I will chose the one who got most "+1". But thanks to all!
This a C-program (apart from the using namespace std;). In C++ you should use streams and formatted I/O, like this:
#include <fstream>
int main() {
std::ifstream input_file("reiz.in");
int n;
input_file >> n; // read one integer
std::ostream output_file("reis.out");
output_file << n * 2 << std::endl; // calculate n * 2 and write the result
// to a file. std::endl adds a newline and
// flushes the buffer
return 0;
}
Pass the address of n to fscanf() (and it's an integer not a string):
fscanf (inFile, "%d", &n);
All that stuff is a bit long in the tooth, unless you are actually writing 'C'. Look at the iostream family of classes if you are writing 'C++'
There are multiple issues with your code:
#include <stdio.h>
This is a C include, not a C++ include. Instead, you should use:
#include <cstdio>
fscanf (inFile, "%s", n);
The format %s is for strings, of type char*. You want to read a decimal number, so use %d instead. Furthermore, you have to pass the address of the destination:
fscanf (inFile, "%d", &n);
fprintf (outFile, "%n", n);
The format %n is used to query the number of bytes written so far, and requires a pointer. Since you want to write a decimal number, use %d again:
fprintf (outFile, "%d", n);
There are two problems with fscanf. First, your format string is wrong -- you're taking a string, where you should be taking a (signed?) decimal. Second, you are passing n by-value, but you should be passing a pointer to n instead:
fscanf (inFile, "%d", &n);
You are also #includeing the now-deprecated <stdio.h> file. You should:
#include <cstdio>
Finally, you claim to be writing C++ code, but the code you actually wrote is decidedly not C++-ish, which is to say it is type-unsafe. I'd recommend you either go C++, or don't -- don't pussyfoot around.
Here is a more C++ way of doing what you're trying to do (you should add error-checking and writing to the output file):
#include <cstdio>
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream in("reiz.in", std::ios::in);
int n = 0;
in >> n;
return 0;
}
There are several issues which will prevent your code from working properly.
There is no need to open outfile as r+. You can just open it with mode w.
outFile = fopen ("reiz.out","w");
When you read from the file with fscanf, you are passing the integer n instead of the pointer to the integer n. fscanf is expecting to receive the location to write the integer it read. You are passing the integer itself (which will, in the best case, crash your program. Worst case, weird stuff will start happening).
fscanf (inFile, "%s", &n);
You are using %n when writing to outfile. This does not print the integer n but rather it reads the number of bytes written so far. You want to use %d instead.
fprintf (outFile, "%d", m);
Also, as a side-note, you seem to be using C instead of C++. In C++, you would usually use file stream objects, like ifstream and ofstream, to read from and write to files. You are using things like fopen which are decidedly more C-like.
This code should work better:
#include <stdio.h>
int main() {
int n;
FILE * inFile;
FILE * outFile;
inFile = fopen ("reiz.in","r");
outFile = fopen ("reiz.out","w");
fscanf (inFile, "%d", &n);
int m = n * 2;
fprintf (outFile, "%d\n", m);
fclose (inFile);
fclose (outFile);
return 0;
}
Go use iostream (Bjorns answer)
But I think
outFile = fopen ("reiz.out","r+");
should be
outFile = fopen ("reiz.out","w+");
Also
fscanf (inFile, "%d", n);
should be
fscanf (inFile, "%d", &n);
For ease of reference, a fully working (C) program:
#include <stdio.h>
int main() {
int n;
FILE * inFile;
FILE * outFile;
inFile = fopen ("reiz.in","r");
outFile = fopen ("reiz.out","w+");
fscanf (inFile, "%d", &n);
int m = n * 2;
fprintf (outFile, "%i", m);
fclose (inFile);
fclose (outFile);
return 0;
}