C++ system() causes "Text file busy" error - c++

I need to execute multiple times a FORTRAN program, that requires the user to insert 4 numeric values each time.
I found a solution to make this automatically with a Python script...this script basically creates at each iteration a .sh file containing the following lines (a.out is the name of the FORTRAN program I have to execute automatically)
./a.out<<EOF
param01
param02
param03
param04
EOF
makes it executable, and executes it.
So, I'm trying to do the same in C++...I wrote something like
int main()
{
long double mass[3] = {1.e+10,3.16e+10,1.0e+11};
double tau[3] = {0.5,0.424,0.4};
double nu[3] = {03.0,4.682,10.0};
long double Reff[3] = {1.0e+3,1.481e+3,3.0e+3};
int temp=0;
for (int i=0; i<3; i++)
{
ofstream outfile("shcommand.sh");
outfile << "./a.out<<EOF" << endl << mass[i] << endl << nu[i] << endl << Reff[i] << endl << tau[i] << endl << "EOF" << endl;
temp=system("chmod +x shcommand.sh");
temp=system("./shcommand.sh");
}
return 0;
}
but when I run my C++ program, I get the following error message
sh: 1: ./shcommand.sh: Text file busy
sh: 1: ./shcommand.sh: Text file busy
sh: 1: ./shcommand.sh: Text file busy
Has it something to do with the C++ program trying to modify the .sh file before the previous iteration is finished?
I looked online, and I seemed to understand the system() command onlyreturns after the command has been completed...

You are trying to run an open file, which isn't such a good idea. Close it before chmodding/running it:
for (int i=0; i<3; i++)
{
{
ofstream outfile("shcommand.sh");
outfile << "./a.out<<EOF" << endl << mass[i] << endl << nu[i] << endl << Reff[i] << endl << tau[i] << endl << "EOF" << endl;
// the file is closed when outfile goes out of scope
}
temp=system("chmod +x shcommand.sh");
temp=system("./shcommand.sh");
}
Incidentally, all this shell mess can be avoided by writing straight to the standard input of your program (e.g. with popen):
for (int i=0; i<3; ++i) {
FILE *fd = popen("./a.out", "w");
assert(fd!=NULL); // do proper error handling...
fprintf(fd, "%Lf\n%f\n%Lf\n%f\n", mass[i], nu[i], Reff[i], tau[i]);
fclose(fd);
}

It seems because the shell cannot read the script because it is still opened by your program.
Try adding outfile.close(); before calling system().

Related

ofstream/fstream simply will not work, no matter what solution is tried

Okay guys, I've tried everything I can think of. I'm passing in a file name into this function. A little context: hash_table is an already initialized and filled vector with key pairs, and the 'value' part of the pair is a Linked List that has the field "bucket_size". When I use cout to check if these fields are actually being accessed, they are; even the debugger lists them as being filed into the output stream. I have flush() and close() in there, but it doesn't write anything to the file. Returns true, indicating no errors in the stream. Anyone have nay ideas?
string line;
std::ofstream ofs;
if(ofs.is_open())
ofs.close();
ofs.open(filename);
if (ofs.is_open())
{
cout << "File Opened" << endl;
for (double i = 0; i < hash_table.capacity(); ++i)
{
ofs << "Bucket Number " << i;
if (hash_table[i].value != NULL)
ofs << " Bucket Size: " << hash_table[i].value->bucket_size << endl;
else
ofs << " Bucket Size: 0" << endl;
ofs.flush();
}
cout << "closing file stream" << endl;
ofs.flush();
ofs.close();
if (ofs.good())
return true;
else
return false;
}
else
{
cout << "File not opened" << endl;
return false;
}
}
You're almost certainly examining the wrong file. Remember that relative paths are relative to the working directory of the process, which is not necessarily the same as where the executable lives on disk.
I compiled and ran it by the console and now it works, with no edits made. It seems my IDE doesn't like something in the code. Regardless, thank you everyone for the response.s

C++ ios:fail() flag

I am trying to read a las file larger then 2GBs (about 15GBs) but ios::fail() flag becomes true in 345th byte. Here is the code below.
void Foo()
{
char* filename = "../../../../../CAD/emi/LAS_Data/AOI.las";
ifstream m_file (filename);
char c;
int count = 0;
if (m_file.is_open())
{
while ( m_file.good() )
{
m_file.get(c);
cout << c << endl;
count++;
}
// Check State
if(m_file.fail())
cout << "File Error: logical error in i/o operation." << endl;
if(m_file.eof())
cout << "Total Bytes Read: " << count << endl;
m_file.close();
}
else
{
cout << "File Error: Couldn't open file: " << endl;
}
}
And the output is:
...
File Error: logical error in i/o operation.
Total Bytes Read: 345
What am I missing?
I'm going to guess that you're using Windows. Windows has a quirk that a Control-Z marks the end of a text file, no matter how large the file actually is. The solution is to open the file in Binary mode.
ifstream m_file (filename, std::ios::binary);

Using Sleep() prevent me to writing to a file

I have some code that writes the system time to a file:
std::ofstream file("time.txt");
char *date;
time_t timer;
timer=time(NULL);
date = asctime(localtime(&timer));
while ( true ) {
std::cout << date << ", " << randomNumber << std::endl;
if (file.is_open())
{
file << date;
file << ", ";
file << randomNumber;
file << "\n";
}
}
file.close()
When I let my program run and stop it in-between (its an infinite while loop), I am able to get data written to my file.
However, if I merely change the code to add a Sleep() timer. No data is written to my file. But I do see an output on the screen. Is this expected behavior? How do I ensure that even if I end my program execution mid-way, values are written to the file?
std::ofstream file("time.txt");
char *date;
time_t timer;
timer=time(NULL);
date = asctime(localtime(&timer));
while ( true ) {
**Sleep(100); // wait for 100 milli-seconds**
std::cout << date << ", " << randomNumber << std::endl;
if (file.is_open())
{
file << date;
file << ", ";
file << randomNumber;
file << "\n";
}
}
file.close()
If I close my file right after the sleep timer, it writes the data out. But the main reason I'm adding the timer, is that I want to slow-down how often my file is being written to ...
You need to flush the buffer so the contents are written to the file. Call std::flush or change file << "\n"; to file << std::endl; to flush the stream. When you don't call Sleep in your program, the contents of the buffer are written as soon as the buffer becomes full, however, with Sleep the buffer doesn't become full right away because there is a delay, so you don't see the contents written to the file.

How to read and write input file and output file

I am trying to run the following program:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
ofstream outFile;
double first=1.49, second=2.59, third=3.69, fourth=4.79;
inFile.open("prices.txt");
char response;
if(!inFile.fail())
{
cout << "A file by the name prices.txt exists.\n" << "Do you want to continue and overwrite it\n" << " with the new data (y or n);"; cin >> response;
if(tolower(response) == 'n')
{
cout << "The existing file will not be overwritten." << endl;
return -1;
}
}
outFile.open("prices.txt");
if (inFile.fail())
{
cout << "\n The file does not exist and can not be opened" << endl;
cout << "The file has been successfully opened for output." << endl;
outFile << first << "\n" << second << "\n" << fourth << "\n" << endl;
outFile.close();
exit(1);
cout << "The file has been successfully opened for output. " << endl;
outFile << first << "\n" << second << "\n" << third << "\n" << fourth << endl;
outFile.close();
return 0;
}
}
Yet this program will not write the values to the prices.txt file. If you run the program once it says the file does not exist. Running it a second time says the file is already there and if you want to overwrite it. The thing is searching my Mac I cannot find this file anywhere.
Any ideas what I am doing wrong with running it in Xcode? A friend runs the exact same code in Visual Studio 2008 and it works. Any help is appreciated.
You need to set the working directory for the executable since you are assuming that your data files are in the current working directory. In Xcode 3.x you set this in the first tab of Get Info for the executable. In Xcode 4.x it has been moved, but the principle is the same.
Alternatively you can change your data file paths (e.g. make them absolute) so that you do not make assumptions about the current working directory.
You may not have permission to write into the directory that you are trying to save the file too.
Also, there is an error in your program and I am sure if it is there for debugging reasons. You have
outFile.close();
exit(1);
But then shortly there after you try to write to the file, then close it again.

XCode will not take input from a file

For some reason, Xcode will not take input from a file, while Visual C++ will.
When I run this program in xcode, the variables numberRows and numberCols stay 0 (they are initialized to 0 in the main function).
When I run it in Visual C++ they become 30 and 30 (the top line of maze.txt is "30 30" without the quotes).
Any ideas why this is happening?
void readIn(int &numberRows, int &numberCols, char maze[][100]){
ifstream inData;
inData.open("maze.txt");
if (!inData.is_open()) {
cout << "Could not open file. Aborting...";
return;
}
inData >> numberRows >> numberCols;
cout << numberRows << numberCols;
inData.close();
return;
}
There is something else wrong.
Unfortunately it is hard to tell.
Try flushing the output to make sure you get the error message:
void readIn(int &numberRows, int &numberCols, char maze[][100])
{
ifstream inData("maze.txt");
if (!inData) // Check for all errors.
{
cerr << "Could not open file. Aborting..." << std::endl;
}
else
{
// Check that you got here.
cerr << "File open correctly:" << std::endl;
// inData >> numberRows >> numberCols;
// cout << numberRows << numberCols;
std::string word;
while(inData >> word)
{
std::cout << "GOT:(" << word << ")\n";
}
if (!inData) // Check for all errors.
{
cerr << "Something went wrong" << std::endl;
}
}
}
interesting, so I followed the following suggestion from this post http://forums.macrumors.com/showthread.php?t=796818:
Under Xcode 3.2 when creating a new
project based on stdc++ project
template the target build settings for
Debug configuration adds preprocessor
macros which are incompatible with
gcc-4.2:
_GLIBCXX_DEBUG=1
_GLIBXX_DEBUG_PEDANTIC=1
Destroy them if you want Debug/gcc-4.2
to execute correctly.