C++ about stdio.h changing stdout
I have a function which prints out some data.
//overallSummary is a void return type function that prints data out to the console. It's works as expected.
I wanted to save to a text file, so this is I did instead
#include <stdio.h>
freopen("summary.txt","w",stdout);
overallSummary();
fclose(stdout);
I ran the code, and it worked as expected.
However, the console kept blinking. It looked like it was blocked. Pressing enter didn't stop it. It wasn't hanging. I just lost the control of the console. Why?
I recommend changing to a more expressive:
#include <iostream>
void overallSummary(std::ostream& os); // use os instead of std::cout in overallSummary
std::ofstream ofs;
ofs.open("summary.txt");
if(!ofs.is_open())
abort();
overallSummary(ofs);
ofs.close();
Otherwise if you just wanna write to a file, that means redirecting std::cout,
so call it like this:
./program_name > summary.txt
In the program writing on std::cout goes into summary.txt. Using ">>" instead of ">" appends.
Related
So i'm making an extremely simple guessing console game and i want to store data permanently in a file (highscore). However everytime i compile the file i'm using empties itself. Is there anyway to stop that?
I've tried a lot of thing which didn't work and i honestly don't know where the problem is. I'm guessing it has to do with the fin and fout but for others it seemed to work
#include <iostream>
#include <fstream>
#include <time.h>
#include <conio.h>
int hs;
//this would be the play_game() function, unrelated to the subject
int main()
{
std::ofstream fout;
fout.open("HS.txt");
std::ifstream fin;
fin.open("HS.txt");
srand(time(NULL));
//menu with 4 options, play, quit, help and highscore (which i'm working on)
fin.close();
fout.close();
}
Don't open your file twice in parallel with two streams. Also, a simple open-for-writing will not truncate your file, but will place you at the start of the file, so you'll be overwriting existing data; see this question. You have to open files with the write mode.
You need to either:
Open your file for both input and output - and without truncating it; see: What does it mean to open an output file as both input and output? , or
Open your file for reading only when your app starts, and open it for writing, and write to it, when it exists (or every once-in-a-while for better resiliency).
I want to read in one file line-by-line and output each line I read to a new file. In this code, cin has been redirected to refer to the input file, and cout has been redirected to refer to the output file.
The loop successfully writes every line in the file, but then it gets stuck on the final getline call. As a result, "Done" is not written to the file and the program does not terminate.
#include <string>
#include <iostream>
using namespace std;
int main() {
string line;
while(getline(cin, line)) {
cout << line << endl;
}
cout << "Done";
return 0;
}
Strangely, if I forcibly terminate the program, it seems to suddenly execute as desired, with "Done" being written.
Can someone point me in the right direction? Is there a flaw in the code, or is this some external configuration issue?
Notes: The input file in question ends with a newline character. Also, I do not want to use any includes besides these two.
The code should terminate on end of file (EOF) or any sort of file error. (The getline being called is:
http://en.cppreference.com/w/cpp/string/basic_string/getline
It returns the cin istream and then invokes its boolean conversion operator:
http://www.cplusplus.com/reference/ios/ios/operator_bool/
that checks if badbit or failbit is set on the stream. The failbit state should be set when a read is attempted with the stream already at EOF, or if there is an error.)
Per the comments above, it seems like this does work when the code is run from the shell directly. My guess is Eclipse is doing something complicated where it either intentionally sends the file into the program and then switches to an interactive input mode, or has a bug in which it doesn't close its end of a pipe or pty/tty it is using to send input to the program. (I.e. Eclipse is not binding stdin directly to the file itself in running the program.)
If one wanted to debug it further, one could look at the process state using tools like lsof. (Assuming a UNIXy system.) Might also be worth raising the issue in an Eclipse forum. The IDE is not my area of expertise.
I have a C++ program which has the prototype of the main function as follows:
int main(int argc, char * argv[])
The code hasn't been written by me, but this is a single C file available here.
When I compile this code, and through the command line run it as:
someexe in.txt > out.txt
This gives me an output out.txt which is generated in the same directory by operating on some input from in.txt.
someexe in.txt out.txt
This gives me an output on the command line itself. (without using > operator)
However, instead of passing the command line argument and without using the output redirection > operator, I have been trying to call the main function from another function and passing the parameters myself. If I pass an array of char* {fileDirName, in.txt}, I am not sure how to go about generating an out.txt (since I think > output redirection is an operating system level function available in command line).
Any suggestions would be greatly appreciated
The program in the link is readily available as copy paste and can be tried (main function is written at the last in the above program)
Assuming the aim is to mimic the output redirection feature (> out.txt) of the shell you can do something like:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <iostream>
int main() {
int fd = open("out.txt", O_WRONLY|O_CREAT|O_TRUNC, 0660);
assert(fd >= 0);
const int ret = dup2(fd, 1);
assert(ret >= 0);
std::cout << "Hello redirected world!" << std::endl;
close(fd);
}
You can do similar for stdin also, to mimic the input redirection (< in.txt). These will be preserved across calls to exec() too.
Of course it would be simpler to modify the program to write to the place you wanted given you have the source available.
Note though that dup2(), which "swap" the stdout fd for the one we just opened is non-portable. IIRC open() (as opposed to fopen()) is UNIX specific also)
You can't call another main() from inside the source another program - main() is special.
If you want to reuse this source code as a library you need to rename main() to something else.
However if it is handling input from either a pipe or a file (eg myprog < input.txt or myprog input.txt) in the normal Unix way then that's a little trickier to handle transparently.
The best way would be to call the compiled program as a separate process from within your new program, passing the correct commandline parameters - see the exec() family of calls
I have the following code, running on Suse 10.1 / G++ 4.1.0, and it doesn't write to the file:
#include <fstream>
#include <iostream>
int main(){
std::ofstream file("file.out");
file << "Hello world";
}
The file is correctly created and opened, but is empty.
If I change the code to:
#include <fstream>
#include <iostream>
int main(){
std::ofstream file("file.out");
file << "Hello world\n";
}
(add a \n to the text), it works.
I also tried flushing the ofstream, but it didn't work.
Any suggestions?
If you check your file doing a cat , it may be your shell that is wrongly configured and does not print the line if there is no end of line.
std::endl adds a \n and flush.
Don't know if this is what you tried but you should do:
file << "Hello World" << std::flush;
Update; I'm leaving this answer here because of the useful comments
Based on feedback, I'll modify my advice: you shouldn't have to explicitly call std::flush (or file.close() for that matter), because the destructor does it for you.
Additionally, calling flush explicitly forces an I/O operation that may not be the most optimized way. Deferring to the underlying iostreams and operating system would be better.
Obviously the OP's issue was not related to calling or not calling std::flush, and was probably due to attempting to read the file before the file stream destructor was called.
The destructor should flush and close the file.
I am pretty sure, the error is an another place, either
1) You do not check at the right point in time. At which point do you compare the content of the file, "after" the exits, or do you set a breakpoint before the program exits and then you check the files content?
2) Somehow the program crashes before it exits?
Does
file << "Hello world" << std::endl;
work?
endl inserts a newline and flushes the buffer. Is that what you were referring to when you said that you'd already tried flushing it?
You are working on Linux, which is a POSIX-compliant system. The POSIX standard defines what a line is:
A sequence of zero or more non-newline characters plus a
terminating newline character.
So without the newline character, the file contains 0 lines and is therefore empty.
I need to write all my program output to a text file. I believe it's done this way,
sOutFile << stdout;
where sOutFile is the ofstream object that creates the file like this:
sOutFile("CreateAFile.txt" ); // CreateAFile.txt is created.
When I insert the stdout into the sOutFile object, I get some code which seems to resemble octal [hexadecimal] code or an address of some kind in the text file that I created.
0x77c5fca0
But what's confusing to me is that in my program I use cout several times. Mostly just literal statement. If I'm not mistaken that is the program output.
If this code is an address, would it contain all of my output? Could I read it back in to the program and find out that way?
What can I do to get ALL of my program output written to a text file?
If your program already uses cout/printf and you want to send EVERYTHING you currently output to a file, you could simply redirect stdout to point to a file before your existing calls:
http://support.microsoft.com/kb/58667
Relevant Code:
freopen( "file.txt", "w", stdout );
cout << "hello file world\n"; // goes to file.txt
freopen("CON", "w", stdout);
printf("Hello again, console\n"); // redirected back to the console
Alternatively if you just want Some things to be printed to a file, you just want a regular file output stream: http://www.cplusplus.com/doc/tutorial/files.html
Relevant Code:
ofstream myfile;
myfile.open("file.txt");
myfile << "Hello file world.\n";
printf("Hello console.\n");
myfile.close();
EDIT to aggregate answers from John T and Brian Bondy:
Finally, if you're running it from the commandline, you can just redirect the output as everyone else mentioned by using the redirect operator ">" or append ">>":
myProg > stdout.txt 2> stderr.txt
This is a duplicate of: this question
You can redirect stdout, stderr and stdin using std::freopen.
From the above link:
/* freopen example: redirecting stdout */
#include <stdio.h>
int main ()
{
freopen ("myfile.txt","w",stdout);
printf ("This sentence is redirected to a file.");
fclose (stdout);
return 0;
}
You can also run your program via command prompt like so:
a.exe > stdout.txt 2> stderr.txt
If you want all output in a text file you don't need to code anything extra.
from the command line:
program > output.txt
If you only wish to redirect certain output you can use ostream as dirkgently suggested.
Then you cannot use std::cout anywhere else to print stuff from your program. Change std::cout to a std::ostream and then pass your file or std::cout as required.
sOutFile << stdout;
in C "stdout" is defined as a FILE* variable. It's just a pointer. Outputing it to a file just writes the value of the pointer, in your case: 0x77c5fca0 to the file.
If you want to direct your output to a file either write it the a file in the first place or redirect the output of your program to a file using the command line.