Fail to write to file when I force quit - c++

I have a program that looks like this. I need to consistently write something into a text file but I cannot predetermine when the program is going to end. So I force quit the program.
FILE *f = fopen("text.txt", "w");
while (1) {
fprintf(f, "something");
sleep(1000);
}
The problem is that the text file would be empty. Can anyone give me some suggestions?
I am using XCode to do the job.

Use fflush(f) after fprintf(f) otherwise the data you printed is still in the stream buffers in stdio and hasn't yet reached the filesystem.
Note that doing this very often may dramatically reduce your performance.

Another way to write in files would be to use the append mode and close the file when you don't need it.
while (1) {
FILE *f = fopen("text.txt", "a");
if (f != NULL) {
fprintf(f, "something");
fclose(f);
}
sleep(1000);
}
In your case, if you 'force-quit' during a sleep phase, the file will not be opened at this time.

Related

Get the last string printed in C/C++

I am trying to create a tester using googletest. the problem is that the function that I am testing is returning void and printing a result instead. I want to get the last string printed into the console so I can test the output. the string may include \n.
so I have the function itself:
void f_sequence(char sequenceStr[])
{
//logic...
if(condotion1)
printf("somthing1");
else if(condotion2)
printf("somthing2")
(...)
}
and then the tester:
TEST(TesterGroup, TesterName)
{
f_sequence("input");
EXPECT_EQ("somthing1", /*how do i get the output?*/);
}
Is it possible?
The functions I test are in c, while the Test function itself (the tester) is in c++. the output is printed using printf. I cannot change the function itself. I am using CLion latest version.
Redirect the standard output to a buffer.
Live on Coliru
#include <stdio.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int stdoutSave;
char outputBuffer[BUFFER_SIZE];
void replaceStdout()
{
fflush(stdout); //clean everything first
stdoutSave = dup(STDOUT_FILENO); //save the stdout state
freopen("NUL", "a", stdout); //redirect stdout to null pointer
setvbuf(stdout, outputBuffer, _IOFBF, 1024); //set buffer to stdout
}
void restoreStdout()
{
freopen("NUL", "a", stdout); //redirect stdout to null again
dup2(stdoutSave, STDOUT_FILENO); //restore the previous state of stdout
setvbuf(stdout, NULL, _IONBF, BUFFER_SIZE); //disable buffer to print to screen instantly
}
void printHelloWorld()
{
printf("hello\n");
printf("world");
}
int main()
{
replaceStdout();
printHelloWorld();
restoreStdout();
// Use outputBuffer to test EXPECT_EQ("somthing1", outputBuffer);
printf("Fetched output: (%s)", outputBuffer);
return 0;
}
References: http://kaskavalci.com/redirecting-stdout-to-array-and-restoring-it-back-in-c/
I don't know if it's possible to get what was last printed, but if you control the environment before your test function is called, you can redirect where standard output goes, which lets you write it to a file, which you can then check.
See this old answer which IMO was neglected. The example from it is modified here:
FILE *fp_old = stdout; // preserve the original stdout
stdout = fopen("/path/to/file/you/want.txt","w"); // redirect stdout to anywhere you can open
// CALL YOUR FUNCTION UNDER TEST HERE
fclose(stdout); // Close the file with the output contents
stdout=fp_old; // restore stdout to normal
// Re-open the file from above, and read it to make sure it contains what you expect.
Two ways:
If you're on a POSIX compatibile system, you can redirect the output of the program to a file using >, then read from the file later to confirm that the output is correct.
The other way is something like this:
freopen("output.txt", "w", stdout);
f_sequence();
freopen("/dev/tty", "w", stdout);
for POSIX compatible systems. On other platforms you'd need to change the "/dev/tty" to something else. I'm not aware of a completely portable way to do this.
And then read from output.txt. What the above snippet does is change what stdout is, so that it prints to a file instead of the normal stdout.
One solution: You can write a separate program that executes the function, and in the unit test, you can execute that program as a sub process and inspect the output. This can be done with std::system, but be very careful to not pass any non-constant input to it. You don't want shell injection vulnerability even in a unit test. System specific functions exist that avoid the use of shell in the subprocess.
Another solution, which is possible at least on POSIX: Replace the the standard out / err streams with file descriptors, and read the files afterwards.
Googletest specific: There seems to be testing::internal::CaptureStdout, which appears to implement the idea of replacing standard streams. But as the namespace implies, this is not official API, so may change in future.
There is a solution ( in C ) for an API call ( cmd_rsp ) with source code here, that when called in your program, creates a separate process, and pipes to both stdin and stdout, from which it accepts a command and returns the response via an auto sizing buffer. Similar in concept to popen(...).
A simple use case:
char *buf = NULL;
/// test cmd_rsp
buf = calloc(BUF_SIZE, 1);
if(!buf)return 0;
if (!cmd_rsp("dir /s", &buf, BUF_SIZE))//note the first argument can be any legal command that
//can be sent via the CMD prompt in windows,
//including a custom executable
{
printf("%s", buf);
}
else
{
printf("failed to send command.\n");
}
free(buf);

Standard output hangs after adding fprintf() statement with custom standard error

I have a C++ class Archive with a member function extractData(). This function calls realExtractData(), which is implemented in a separate C library.
I want to pass the extractData() function a pair of FILE * instances that are usually stdout and stderr, but I want to provide the option of custom file pointers, as well:
class Archive {
public:
...
int extractData(string id, FILE *customOut, FILE *customErr);
...
};
int
Archive::extractData(string id, FILE *customOut, FILE *customErr)
{
if (realExtractData(id.c_str(), customOut) != EXIT_SUCCESS) {
fprintf(stderr, "something went wrong...\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
If I call the above as listed, there is no delay in outputting data to standard output. All extracted data get sent to standard output (stdout) almost immediately:
FILE *outFp = stdout;
FILE *errFp = stderr;
Archive *archive = new Archive(inFilename);
if (archive->extractData(id, outFp, errFp) != EXIT_SUCCESS) {
fprintf(errFp, "[error] - could not extract %s\n", archive->getInFnCStr());
return EXIT_FAILURE;
}
If I change extractData() so that its fprintf() call uses customErr:
int
Archive::extractData(string id, FILE *customOut, FILE *customErr)
{
if (realExtractData(id.c_str(), customOut) != EXIT_SUCCESS) {
fprintf(customErr, "something went wrong...\n"); /* <-- changed this line */
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
...then when I run the binary, the binary seems to hang in processing input and printing to standard output.
If I change fprintf() back to using stderr and not customErr, things once again work properly, i.e., data are flushed to standard output (my customOut) immediately.
Is this a buffering issue? Is there a way to fix this?
"stderr and not customErr"
Standard error is un-buffered which means it prints out almost immediately. other output streams are buffered unless you're using low-level OS calls, which means they will take longer to print unless you do a buffer flush with something like an endl, ::flush, or whatever else.
If you want to go for the low-level OS calls and you're working with unix, check this out:
http://www.annrich.com/cs590/notes/cs590_lecture_2.pdf
I haven't read the whole thing, but on scanning it it looks as if it has similar info to the good Stevens Advanced Programming in Unix book which defitely talks through this.

Writing popen() output to a file

I've been trying to call another program from c++, and save the stout of that program to a text file. popen() seems to be the appropriate function, but saving it to a text file isn't working.
ofstream delaunayfile;
delaunayfile.open ("triangulation/delaunayedpoints.txt");
FILE *fp;
fp = popen("qdelaunay < triangulation/rawpoints.txt", "r");
delaunayfile << fp;
delaunayfile.close();
Any help? Thanks in advance!
You cannot write a FILE* directly into a stream. It will write a memory address instead of the actual file contents, therefore it will not give you the desired result.
The ideal solution would be to read from an ifstream and write to your ofstream, but there's no way to construct an ifstream from a FILE*.
However, we can extend the streambuf class, make it work over a FILE*, and then pass it to an istream instead. A quick search revealed someone already implemented that, and properly named popen_streambuf. See this specific answer.
Your code then would look like this:
std::ofstream output("triangulation/delaunayedpoints.txt");
popen_streambuf popen_buf;
if (popen_buf.open("qdelaunay < triangulation/rawpoints.txt", "r") == NULL) {
std::cerr << "Failed to popen." << std::endl;
return;
}
char buffer[256];
std::istream input(&popen_buf);
while (input.read(buffer, 256)) {
output << buffer;
}
output.close();
As pointed by Simon Richter in comments, there's an operator<< that accepts streambuf and writes data to ostream until EOF is reached. This way, the code would be simplified to:
std::ofstream output("triangulation/delaunayedpoints.txt");
popen_streambuf popen_buf;
if (popen_buf.open("qdelaunay < triangulation/rawpoints.txt", "r") == NULL) {
std::cerr << "Failed to popen." << std::endl;
return;
}
output << &popen_buf;
output.close();
There are two ways to do this: The simple way
int rc = system("qdelaunay < triangulation/rawpoints.txt >triangulation/delaunayedpoints.txt");
and the slightly more elaborate way, using fork(), dup2() and execve(), the latter working without a shell interpreter installed on the system. Given that this looks like you are doing computation work, I suspect this is not an embedded system, so you can assume a working shell.
popen opens a pipe but I am not aware you can just stream it into delaunayfile that way.
Of course it would be very nice if you could just do that and it would read from the pipe until it was complete.
The normal way to check for data on the pipe is to use select(). I found a useful link http://codenewbie.com/forums/threads/2908-Using-std-fstream-in-a-pipe that integrates pipes with fstream though and it may help you achieve what you want.
In this instance though as all you want to do is write the output to a file, why not redirect the output of the process to it rather than to a pipe? The purpose of a pipe is Inter-Process communication but your process does not appear to be using the data it receives from the other process for any practical purpose.

close file with fclose() but file still in use

I've got a problem with deleting/overwriting a file using my program which is also being used(read) by my program. The problem seems to be that because of the fact my program is reading data from the file (output.txt) it puts the file in a 'in use' state which makes it impossible to delete or overwrite the file.
I don't understand why the file stays 'in use' because I close the file after use with fclose();
this is my code:
bool bBool = true
while(bBool){
//Run myprogram.exe tot generate (a new) output.txt
//Create file pointer and open file
FILE* pInputFile = NULL;
pInputFile = fopen("output.txt", "r");
//
//then I do some reading using fscanf()
//
//And when I'm done reading I close the file using fclose()
fclose(pInputFile);
//The next step is deleting the output.txt
if( remove( "output.txt" ) == -1 ){
//ERROR
}else{
//Succesfull
}
}
I use fclose() to close the file but the file remains in use by my program until my program is totally shut down.
What is the solution to free the file so it can be deleted/overwrited?
In reality my code isn't a loop without an end ; )
Thanks in advance!
Marco
Update
Like ask a part of my code which also generates the file 'in use'. This is not a loop and this function is being called from the main();
Here is a piece of code:
int iShapeNr = 0;
void firstRun()
{
//Run program that generates output.txt
runProgram();
//Open Shape data file
FILE* pInputFile = NULL;
int iNumber = 0;
pInputFile = fopen("output.txt", "r");
//Put all orientations of al detected shapes in an array
int iShapeNr = 0;
int iRotationBuffer[1024];//1024 is maximum detectable shapes, can be changed in RoboRealm
int iXMinBuffer[1024];
int iXMaxBuffer[1024];
int iYMinBuffer[1024];
int iYMaxBuffer[1024];
while(feof(pInputFile) == 0){
for(int i=0;i<9;i++){
fscanf(pInputFile, "%d", &iNumber);
fscanf(pInputFile, ",");
if(i == 1) {
iRotationBuffer[iShapeNr] = iNumber;
}
if(i == 3){//xmin
iXMinBuffer[iShapeNr] = iNumber;
}
if(i == 4){//xmax
iXMaxBuffer[iShapeNr] = iNumber;
}
if(i == 5){//ymin
iYMinBuffer[iShapeNr] = iNumber;
}
if(i == 6){//ymax
iYMaxBuffer[iShapeNr] = iNumber;
}
}
iShapeNr++;
}
fflush(pInputFile);
fclose(pInputFile);
}
The while loop parses the file. The output.txt contains sets of 9 variables, the number of sets is unknown but always in sets of 9.
output.txt could contain for example: 0,1,2,3,4,5,6,7,8,8,7,6,5,4,1,2,3,0
update 2
code:
void runProgram(){
//Check if output.txt exists, if so delete it
if(fileExists("output.txt") == 1){
//Delete output.txt
if( remove( "output2.txt" ) == -1 ){
//errormessage
}else{
//succesfull
}
}
//start program
ShellExecute( NULL, TEXT("open"), TEXT("program.exe"), NULL, NULL, SW_SHOWMAXIMIZED);
while(fileExists("output.txt") == 0);
//Close program
int iCheck = system("taskkill /IM program.exe");
if(iCheck != 0){
//error could not shut down
}
}
sorry for using pre again but I don't get the formatting of this site :(
Will it be due to maximum disk space has been reached and there's still data in the file
streams buffer; fclose'ing a file stream flushes it (writes all the data in the buffer), the write operation will fail since maximum disk space is reached.
I suggest you to scope down the problem, by calling fclose() directly after fopen().
If it success, then something is wrong in the code between fclose() and fopen().
There is probably other places in your code where you don't call fclose, leaking the file. Even in this code, if an error occurs between fopen and fclose (or a return statement, or a continue statement, etc...) you'll leak the file. Please, switch to RAII idiom.
Edit: include this into your code:
struct PoorMansFile {
FILE *_file;
PoorMansFile(const char* str1, const char* str2) : _file(fopen(str1,str2)) {}
~PoorMansFile() { if(_file) fclose(_file); }
operator FILE*() const { return _file; }
};
int fclose(PoorMansFile& file)
{
if(!file)
return 0;
int t = fclose(file._file);
file._file = 0;
return t;
}
and replace each
FILE* file = NULL;
file = fopen(str1, str2);
with:
PoorMansFile file(str1, str2);
Tell us if it helps;
The file could still be in use by the CRT or OS - for example, the OS may buffer writes to the disk. fflush() will only flush CRT buffers, not OS buffers.
Just a shot in the dark here...
What is inside runProgram()? Does that function wait until the program has finished before returning? I wonder if the program that is writing the data is, in fact, still running... it's difficult to tell from here, but thought I'd throw it out there!
After reading all answers and comments I could not think of any reason of OP's problem.
Is this multi threaded or reentrant routine?
What will happen if fopen twice and fclose twice on the same file? Is this could be the cause of the problem?
In this thought I suggest two more checks.
printf all fopen/fclose call
after fclose reset file variable to NULL
f = fopen("", ""); printf("fopen => %p", f);
fclose(f); printf("fclose => %p", f); f = 0;
If you are inconvenient with printf debugging you can use OutputDebugString.
extern void __stdcall OutputDebugStringA(const char*) (MS VC only)

C/C++ add input to stdin from the program?

Is that even possible ?
Lets say that the code has a lot of scanf lines. Instead of manually running and adding values by hand when debugging, is it possible to "feed" stdin with data so that when the scanf starts reading, it will read the inputted data without any need to interact with the terminal.
Put the test lines into a file, and run the program like this:
myprogram < mytestlines.txt
Better than hacking your program to somehow do that itself.
When you're debugging the code, you can set up the debugger to run it with that command line.
To make your program a little more versatile, you might want to consider rewriting your program to use fscanf, fprintf, etc. so that it can already handle file IO as opposed to just console IO; then when you want to read from stdin or write to stdout, you would just do something along the lines of:
FILE *infile, *outfile;
if (use_console) {
infile = stdin;
outfile = stdout;
} else {
infile = fopen("intest.txt", "r");
outfile = fopen("output.txt", "w");
}
fscanf(infile, "%d", &x);
fprintf(outfile, "2*x is %d", 2*x);
Because how often do programs only handle stdin/stdout and not allow files? Especially if you end up using your program in shell scripts, it can be more explicit to specify input and outputs on the command line.
int fd[2];
pipe(fd);
close(0); // 0:stdin
dup(fd[0], 0); // make read pipe be stdin
close(fd[0]);
fd[0] = 0;
write(fd[1], "some text", 9); // write "some text" to stdin