I have built a .cpp program in order to write some content to a .txt file created within the .cpp file.
I manage to write the desired content, however, when I am trying to open the created file from terminal, it says that it cannot find it although it is there.
When I try to open it with vi or nano it's content it's empty. It is like creating a new file.
However, when I open it outside terminal, I can see its content as I wanted.
What could be the problem and how can I fix this situation?
Bellow, I have added the code.
The problem is with the system(buffer) command. I receive the following error: sh: cannot open video2.txt: No such file. I have tried to opened the files from command prompt and I get the above described situation.
int main(int argc,char* argv[])
{
fstream RawStipFile;
RawStipFile.open(strcat(argv[1],".txt"));
string line;
if (RawStipFile.is_open())
{
getline(RawStipFile, line);
int i = 0;
ofstream OutVideoStip;
ofstream VideoList;
VideoList.open("VideoList.txt");
while ( RawStipFile.good() )
{
getline (RawStipFile,line);
char* l;
l = (char*) malloc(sizeof(char));
l[0]=line[0];
//cout<<line[0]<<endl;
if (line[0]==35)
{
if (OutVideoStip.is_open())
{
OutVideoStip.close();
}
i++;
//char* base;
//base = (char*) malloc(1000*sizeof(char));
//sprintf(base, "%d", i);
char* b;
b = &line[1];
VideoList<<b<<endl;
OutVideoStip.open(strcat(b, ".txt"));
}
else
{
OutVideoStip << line << endl;
}
}
OutVideoStip.close();
RawStipFile.close();
VideoList.close();
}
else
{
cout << "Unable to open file \n";
}
fstream VideoNames;
VideoNames.open("VideoList.txt", fstream::in);
if (VideoNames.is_open())
{
while ( VideoNames.good() )
{
getline(VideoNames, line);
line=line.substr(1,line.length());
if (line.compare(""))
{
string initial = "./txt2mat<";
initial.append(line);
initial.append(".txt>");
initial.append(line);
initial.append(".dat");
cout<<initial<<endl;
const char* buffer;
buffer = initial.c_str();
system(buffer);
}
}
}
else
{
cout<<"Unable to open file. \n";
}
VideoNames.close();
return 0;
}
You are using strcat in a wrong way. I don't know if that's the cause of your problem, but it can result in undefined behavour;
int main(int argc,char* argv[])
{
fstream RawStipFile;
RawStipFile.open(strcat(argv[1],".txt"));
Here you modify argv[1]. You append 4 characters to it, without allocating any memory.
string line;
...
char* b;
b = &line[1];
VideoList<<b<<endl;
OutVideoStip.open(strcat(b, ".txt"));
a string takes care of it's own memory management. You can't asume it has reserved 4 more bytes for you to append. If you need to append, use string member functions, not strcat.
just a loose guess: the current working directory is not the same?
Try either using chdir first or opening by absolute path /home/simon/VideoList.txt
Related
I'm trying to open a file, and modify some contents inside. My first code looks like this,
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char** argv) {
int status = 0;
//error if no filename
if(argc == 1) {
cerr << "No file specified. Please specify a filename" << endl;
status = 1;
}
//open a file and modify
for (int i = 1; i < argc; ++i) {
string line = "";
string filename = argv[i];
ifstream infile;
infile.open(filename);
if(infile.fail()) {
status = 1;
cerr << filename << ": No Such File Exist" << endl;
}
else{
while(getline(infile, line)) {
auto index1 = line.find('(');
auto index2 = line.find(')');
cout << index1 << " " << index2 << endl;
auto itor = line.begin();
if(index1 != string::npos) line[index1] = '[';
if(index2 != string::npos) line[index2] = ']';
}
infile.close();
}
}
return status;
}
I know it's wrong to directly modify line because it won't change the content in the file. Is there a way that I can modify the file directly?(Without creating a new file, and output line to that)
You can:
Store the lines, modified and unmodified, in a std::vector<std::string>.
Close the file.
Open the file in write mode.
Save the lines, stored in the std::vector<std::string> to the file
Close the file.
It will be better to create separate functions for each step.
void readContents(std::string const& filename,
std::vector<std::string>& lines)
{
...
}
void updateContents(std::vector<std::string>& lines)
{
...
}
void WriteContents(std::string const& filename,
std::vector<std::string> const& lines)
{
...
}
and then call the from main.
int main(int argc, char* argv[])
{
...
string filename = argv[i];
std::vector<std::string> lines;
readContents(filename, lines);
updateContents(lines):
writeContents(filename, lines):
}
If the data you want to change doesn't change the size of the file in any way (i.e. you're not trying to write data that is longer or shorter than the existing data in the file) then yes it's possible, just overwrite the existing data once you find it, by changing the write position.
If, on the other hand, the data is of a different size, then it's very hard to do (you need to read everything and reposition it within the file), it's much easier to just write a new file and rename it.
Changing one kind of brace to another will not change the size of the file, so then you can easily do it. Just go through the file one character at a time, when you find a character you want to change, set the write pointer to the position of the character and write the new character.
I tried making a program earlier that tells the user then number of char, words, and lines in a text file. I made functions to determine the numbers of each, yet I was passing them by value. This resulted in an error since after reading the number of char it would be at the end of the file and then output zero for the other two. Now I cant seem to rewrite my functions so that the file is open and closed each time its checked for char, words, and lines. Any one see where my errors are?? Thanks! (just copied and pasted one of my functions for now).
int num_of_lines(ifstream file)
{
string myfile;
myfile = argv[1];
ifstream l;
l.open(myfile);
int cnt3 = 0;
string str;
while(getline(file, str))cnt3++;
l.close();
return(cnt3);
}
int main(int argc, char **argv)
{
int num_of_char(ifstream file);
string file;
file = argv[1];
if(argc == 1)die("usage: mywc your_file");
ifstream ifs;
ifs.open(file);
if(ifs.is_open())
{
int a, b, c;
a = num_of_lines(ifs);
cout <<"Lines: " << a << endl;
}
else
{
cerr <<"Could not open: " << file << endl;
exit(1);
}
ifs.close();
return(0);
}
There is no way to "reopen" a file other than knowing the name and creating a new ifstream, but you can use the seekg member function to set your read position in the file, and setting it to 0 will have the next read operation start from the beginning of the file.
A stream is not possible to copy, so you can't pass it "by value", but must pass it by reference.
int num_of_lines(ifstream &file)
{
int count = 0;
string str;
while (getline(file, str)) {
count++;
}
file.seekg(0);
return count;
}
For the full problem, I agree with Mats Petersson, though. Counting both characters, lines and words in one pass will be much more efficient than reading through the file three times.
I have a file that I want my program to read from using input redirection from the command line. For example,a.out < file.dat . Then I was going to use cin.get() and put characters in an array.
I don't want to hard code any input file names, which I have been seeing in some of the existing posts. If I treat this input redirection as stdin, do I have to explicitly open my file?
int main (int argc, char *argv[])
{
string filename;
ifstream infile;
cin >> filename;
do {
int c = 0;
c = infile.get(); //need to get one character at a time
//further process
} while ( ! infile.eof());
}
You can just use cin, which is a stream buffer associated with stdin
#include <iostream>
int main()
{
char c;
while (std::cin.get(c))
{
std::cout << c << std::endl; // will print out each character on a new line
}
exit(0);
}
Here's my code.
ifstream readFile;
readFile.open("voltages.txt");
if (readFile.fail( ) )
{
cout << "\nCould not open the file ... check to see if voltages.txt exists\n";
system("pause");
return;
}
string tempString = "";
//readFile.seekg(0, ios::beg);
int idx = 0;
if (readFile.is_open())
{
while ( readFile.good() )
{
getline(readFile,tempString);
cout << tempString << endl;
}
readFile.close();
}
If I move the voltages.txt to c:/, then it works fine, but I have it in the same folder as my .exe right now, and when I set a breakpoint at cout << tempString << endl; it shows up just as "". I'd like to keep it in the .exe if possible. As you can see I tried seeking to the beginning, with no luck. Please help this C++ noob! Thank you!
It might be because you are trying to read a local file when the program requires a link to the file from C:/
You can test this by replacing voltages.txt with C:/pathToVoltages/voltages.txt
I would suggest passing the file to your executable by doing this:
int main(int argc, char argv[]){
ifstream readFile;
readFile.open(argv[2]);
/*Rest of the code*/
This assumes the path to the file is given by the first argument you give to the program as in:
./program pathToFile/voltages.txt
Hope this helps
I've narrowed my code down, and I found the source of the problem, it's when I open a file.
The file does exists, and I don't get any warning or errors when compiling.
int main(int argc, const char* args[])
{
cout << "Wellcome" << endl;
cout << args[1];
ifstream exists(args[1]);
if(!exists)
{
printf("FILE NOT FOUND");
return 1;
}
exists.close();
ifstream* in;
in->open(args[1],ios::binary|ios::in);
//do stuff
in->close();
return 0;
}
You have created a pointer to an ifstream object, but you never allocated an ifstream for it to point to. To fix this, consider just stack-allocating it:
ifstream in;
in.open(args[1],ios::binary|ios::in);
//do stuff
in.close();
In general, you usually don't need to dynamically allocate objects unless you want them to outlive the function that created them.
Hope this helps!