Errors in relative path - c++

So this is a simple C++ program for reading a file and displaying its contents.
My directory structure is as follows
Project Directory
|
Data___
| |
| data.txt
|
program1.cpp
and The program:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
char char1;
fstream data; // Because I wanna to write to this file later.
data.open("../Data/data.txt",ios::out | ios::in);
if (data.is_open()) {
for (int i = 0; !data.eof(); ++i) {
data.get(char1);
cout << char1 << endl;
}
data.close();
}
return 0;
}
So currently my program works fine... However when I use:
data.open("Data/data.txt",ios::out | ios::in);
The program doesn't work. Why is this so? Ideally the above mentioned code piece should work since the Data folder is in the same directory as my cpp file.
data.open("../Data/data.txt",ios::out | ios::in);
By using 2 dots we are going back a directory and the Data folder isn't there.
Then why is the program working using the 2 dots?

Looking at your directory structure, I see that both your program1.cpp and data.txt are in the same "Data" folder. Since you are already inside the Data folder, "Data/data.txt" looks for another Data folder. In UNIX ".." means the previous directory. So when you use ".." you go to "Project Directory", which contains a "Data" folder. That is why data.open("../Data/data.txt",ios::out | ios::in) is working. You can also try using the following:
data.open("data.txt",ios::out | ios::in);

Related

Input Output with fstream

Can anyone tell me what is wrong with this code? I always get not open.
#include <iostream>
#include <fstream>
using namespace std;
int main(){
fstream fs;
fs.open("fsfile2",ios::in|ios::out|ios::binary);
if(fs.is_open()){
fs.write("wow",sizeof("wow"));
char str[20];
fs.read((char*)str,sizeof(str));
cout<<str<<endl;}
else
cout<<"Not open\n";
return 0;
}
Try this code
fs.open("fsfile2", ios::app|ios::in|ios::out|ios::binary);
By using the open() like you are that file will not be created if that is your goal.
If you want to create a new file please look at: fstream won't create a file
If the file exists, you are not looking for it in the right path. Or change the file name to the full path or put the executable in the folder where the file is.
Hope this helps.
Probably, you do not have permissions to create files in the directory, where your executable is.
Solution:
Please add a file extension to the filename.
If it's a text file, it will be
"fsfile2.txt"
Then, I tried removing
ios::in
since the first process only writes to file, and by removing that, the file is created and "wow" is also written at it.
In order for these lines
fs.read((char*)str,sizeof(str));
cout<<str<<endl;
to work,
You need to close the stream after writing to it, then open the stream in read mode, then read the contents. Take note that closing the stream will save the edited file.
Additional:
You can also change
fs.write("wow",sizeof("wow"));
to
fs << "wow";
You can do the same when reading from file,
fs >> str;
You can also use the string class of C++, instead of char array so that the number of characters inside the file won't be your problem anymore.
#include <string>
string str;
Checking for EOF (end-of-file) is recommended since files are read line by line. Once you add a new line and add a character to the line, the code that doesn't loop until EOF will only read the first line of the file.
In order to solve this, it is recommended to loop until EOF is reached.
while(!fs.eof()) {
fs >> str;
cout << str << endl;
}
So here is the improved snippet:
#include <string>
fs.open("fsfile2.txt", ios::out); // ios::out for write only
if(fs.is_open()) {
// writes "wow" to file
fs << "wow";
// closes the file
fs.close();
// ios::in for read only
fs.open("fsfile2.txt", ios::in);
// better to define variable just before using it
string str;
// loops until end-of-file
while(!fs.eof()) {
// reads a line from file, stores it to str
fs >> str;
// shows str to screen
cout << str << endl;
}
}
*Note: I removed
ios::binary
Since your code is not dealing with binary files yet.
I tried these and it worked fine! Have a nice day!
fstream fs; does not create a new file for you.
You need to make sure that the file exists in your project directory.
On the other hand, if you were to use ofstream fs("file.txt"); it would create the file for you. Or use only ios::out when you open fstream fs, this will create the file for you.

fstream doesn't resolve path

i am new to c++ and trying to write a simple function, that saves a string to a file.
The function works, when i pass the full path to fstream, but it doesn't resolve relative paths.
Here is the relevant part of my code
#include <iostream>
#include <fstream>
void writeToFile ()
{
std::fstream fs;
fs.open ("/home/blabla/Documents/test.txt", std::fstream::in | std::fstream::out | std::fstream::app);
fs << " test content";
fs.close();
}
This works fine, but i would like to create the file in the folder, where my program is executed, so i tried this
fs.open ("./test.txt", std::fstream::in | std::fstream::out | std::fstream::app);
I also tried
fs.open ("~/Documents/test.txt", std::fstream::in | std::fstream::out | std::fstream::app);
Neither of them created a new file and i did not get any error message.
I found this post, which suggests, that i can pass relative paths to fstream but only gives windows examples.
How to use fstream objects with relative path?
I work on Linux Mint, the target environment is debian.
I am thankful for any hints or suggestions,
Michael
Relative paths do work with streams. You have two interesting cases though. The tilde (~) is a special character that some shells interpret. I suspect that fstream doesn't do that interpretation. As to the example of "./test.txt", I think the previous comment is correct - that file has been created - it's just not where you expected it.
Your program
#include <iostream>
#include <fstream>
void writeToFile () {
std::fstream fs;
fs.open ("./test.txt", std::fstream::in | std::fstream::out | std::fstream::app);
fs << " test content";
fs.close();
}
int main() {
writeToFile();
}
works perfectly fine for me on Coliru.
As you can see from the ls output, the file was created
a.out << The executable program
main.cpp << The source
test.txt << The created text file
and cat at least dumps the content of the file
test content
As mentioned in my comment, a path like ~/Documents/test.txt is evaluated by the shell, while ./test.txt should work for openting an existing file, if you're running your program in the same directory where the file exists.
"Neither of them created a new file and i did not get any error message."
You'll never get any kind of error message, if std::fstream::open() failed for some reason.
You have to check for the stream state after that call, like e.g.
if(!fs) { std::cerr << "Could not open file" << std::endl; }
You may e.g. not have rights to create a file in this directory.
Another option is to use the std::basic_ios::exceptions() function of std::fstream(), to trigger an exception when the stream state runs into an error condition.

Error reading txt file c++

I have this code that suppose to read a txt file.
But for some reason i am always getting *File not found that means that fileIn.fail() failed...
#include <iostream>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
using namespace std;
int main ()
{
string fileName;
ifstream fileIn;
bool x;
cout << "enter file name \n";
cin >> fileName;
fileIn.open(fileName);
if(fileIn.fail())
{
cerr << "* File not found";
return true;
}
the file located in the same folder as my main.cpp file and named input.txt. I have tried to set the fileName hard coded but this also didn't work.
What is wrong with my code?
here is the project:
Here is a checklist:
Do you have permissions to read/access the file?
Are you the owner of the file?(Linux)
Are you giving the correct path, relative or absolute from the executable?
If the answer to any of these is a no, then that is where the problem lies, not just "file not found" error.
--EDIT--
#VladIoffe the executable I see there, is qustion2 and the relative path you have to give is ../input.txt and not input.txt
You should use absolute path to the fileName.
Absoulut path will always works. But I hate full path I prefer relative path for a simple reason: code is more portable.
If you run your program with input.txt in the same path of executable it will work. But when you use an IDE you must set the current directory in the IDE settings.

C++ code not finding file

I'm trying to create a program that will concatenate (add two lists of integers together)
each list is stored as a text file. I want the C++ program to open list1.txt and list2.txt
I can't actually get it to work though. I've put two lists of integers names list1 and list2 respectively however I'm getting the output cannot find list1.
#include <iostream>
#include <fstream>
#include <ostream>
using namespace std;
int main()
{
ifstream findlist1("list1.txt", ios::in | ios::binary);
if(!findlist1)
{
cout << "Cannot find list 1.\n";
return 1;
}
ifstream findlist2("list2.txt", ios::in | ios::binary);
if(!findlist2)
{
cout << "Cannot find list 2.\n";
return 1;
}
ofstream out("list3out.txt", ios::out | ios::binary);
if(!out)
{
cout << "Unable to output file ";
return 1;
}
out << in1.rdbuf();
out << " " << flush;
out << in2.rdbuf();
return 0;
}
EDIT = SOLUTION:
My files were called test1.txt and were therefore showing up to the program as test1.txt.txt
The code looks fine, you may try using absolute path or put the files in the same directory of executable
If you are using Visual Studio, all relative paths are relative to the project's working directory. The default seems to be the project directory - meaning that if in C:\SolutionX\ProjectY\Build\ProjectY.exe you try to open the path "file.txt", Windows will look for C:\SolutionX\ProjectY\file.txt. If you'd like to change this directory, the setting is in the project's Configuration Properties under Debugging as "Working Directory".
Note that if you double click the executable manually rather than running it through Visual Studio, its working directory will be its current location. If instead you run the program from a command line, the working directory will be your working directory in the command line.

Appending a new line in a file(log file) in c++

I have a logging functionality and in this I have got log files. Now every time I run the program I want that previously written file should not get deleted and should be appended with the current data (what ever is there in the log file)
Just to make it clear for example: I have a log file logging_20120409.log which keeps the timestamp on a daily basis. Suppose I run my project it writes to it the current timestamp. Now if I rerun it the previous timestamp gets replaced with it. I do not want this functionality. I want the previous time stamp along with the current time stamp.
Please help
You want to open the file in "append" mode, so it doesn't delete the previous contents of the file. You do that by specifying ios_base::app when you open the file:
std::ofstream log("logfile.txt", std::ios_base::app | std::ios_base::out);
For example, each time you run this, it will add one more line to the file:
#include <ios>
#include <fstream>
int main(){
std::ofstream log("logfile.txt", std::ios_base::app | std::ios_base::out);
log << "line\n";
return 0;
}
So, the first time you run it, you get
line
The second time:
line
line
and so on.
Use something like:
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ofstream out("try.txt", ios::app);
out << "Hello, world!\n";
return 0;
}
The ios:app option makes the output get appended to the end of the file instead of deleting its contents.
maybe you need to open the file with the append option. like this:
FILE * pFile;
pFile = fopen ("myfile.txt","a");
or this :
fstream filestr;
filestr.open ("test.txt", fstream::app)