Cant open file using c_str() in linux - c++

On Windows, I have no problems opening the file from string. On Linux (where it needs to work) I can't open the file.
string name;
//open 1st file, with the next file name - this works
fstream file( "data.dat", ios::in);
if(file.good()){
getline(file, name);
//some code here
file.close();
}else{
return 1;
}
// this here does not work
fstream file1(name.c_str() , ios::in);
if(file1.good()){
//some code here
file1.close();
}else{
cout<<"can't open file"<<endl;
return 1;
}
If instead name.c_str() I write the file name directly it works, but every try on getting the name from the file ended with the file not opening.
I've tried creating const char* from name, doesn't work too.

The file probably has Windows-style line endings. Either sanitise the file, or check for and remove any carriage-return character, \r, at the end of each line.

Related

Why SFML isn't able to load an image. SFML, C++ [duplicate]

ifstream myfile;
myfile.open("FileTest");
string line;
if(myfile.is_open())
{
cout<<"Reading from file...";
getline(myfile,line);
}
if(myfile.fail())
{
cout<<"Unable to open file"<<endl;
}
myfile.close();
C++ tries to open the file in the current directory with the exact name FileTest. Check to see if the file is in the current directory? Maybe you spelled the name incorrectly? Maybe you forgot to write FileTest.txt? You are using ifstream, which will fail if the file you're trying to open does not exist or is corrupted.

How to read text from file itno standard string cpp

I am trying to read about 2 lines from a file of text into a std::string in c plus plus. I have looked through several answers and found none that work on my device. Can anyone tell me what I am doing wrong? The method is currently returning a null string, and doesn't correctly open the file or read it at all.
std::string readFile(std::string filename) {
std::ifstream infile;
infile.open(filename);
std::string output;
if (infile.is_open()) {
while(infile.good()) {
infile >> output;
}
}
infile.close();
return output;
}
Not sure what file you are trying to open but that's a completely separate problem. The code you've written will open a file if you give it a path to a file that it can open. Check your current working directory and confirm the path is correct.
Even after you solve that problem, you're going to have more problems though.
I expect that you are confused because you are repeatedly overwriting output with this line:
infile >> output;
perhaps you meant to declare output as a std::stringstream
And for me it doesn't return an empty string, it returns the last word of the file. I guess it depends what's in your file.

Erase empty lines from a text file in C++

I have a text file, which may contain some empty lines. I want to open this file and look for the empty lines. If an empty line exists then, I want to delete that line. I do not want to create a temporary file for this purpose. I want to edit the same file and close it afterwards.
I have already seen a couple of posts about similar problem but none of them worked for me.
void DeleteEmptyLines(const string& FilePath)
{
//EXISTING File
std::fstream FileStream;
std::string CurrentReadLine;
if (doesFileExist(FilePath))
{
FileStream.open(FilePath, std::fstream::in | std::fstream::out | std::fstream::app);
//Read all the lines till the end of the file
while(getline(FileStream, CurrentReadLine))
{
//Check if the line is empty
if(CurrentReadLine.empty())
{
cout<<"Empty line found"<<endl;
//DELETE THIS EMPTY LINE
}
}
FileStream.clear();
FileStream.close();
}
// else --->> do nothing
}
Current File (MyFile.txt):
Line1
Line2
Line3
What I need (MyFile.txt):
Line1
Line2
Line3
PS: I am using VS2010 on windows machine.
Simple solution. Reads file into a string skipping empty lines, then overwrites the file with the contents of the string.
void DeleteEmptyLines(const std::string &FilePath)
{
std::ifstream in(FilePath);
std::string line, text;
while (std::getline(in, line))
if !(line.empty() || line.find_first_not_of(' ') == std::string::npos)
text += line + "\n"
in.close();
std::ofstream out(FilePath);
out << text;
}
EDIT: #skm The new answer you posted does not erase lines with empty spaces, as you stated.
To fix this use this condition to make sure a line is not "empty":
!(CurrentReadLine.empty() || CurrentReadLine.find_first_not_of(' ') == std::string::npos)
You can't do it in all currently used filesystems, because data is stored successively. So do 'delete' some bytes from file you have to move all subsequent bytes at that amount of bytes. And you can't open file for reading and at that moment rewrite it from beginning.
So you have 3 options:
Read all file into memory and then rewrite lines to the original
file skipping empty lines.
Read file line by line, save only
non-empty lines into memory, and then write then down to the same file.
Use temporary file, which is actually a good choice because you
don't have to have a lot of RAM and file moving operation is
low-cost at most filesystems (if source and destination are at the
same partition).
I have modified my function as following.
void DeleteEmptyLines(const string& FilePath)
{
std::string BufferString = "";
//File
std::fstream FileStream;
std::string CurrentReadLine;
if (doesFileExist(FilePath))
{
FileStream.open(FilePath, std::fstream::in); //open the file in Input mode
//Read all the lines till the end of the file
while(getline(FileStream, CurrentReadLine))
{
//Check if the line is empty
if(!CurrentReadLine.empty())
BufferString = BufferString + CurrentReadLine + "\n";
}
if(DEBUG) cout<<BufferString<<endl;
FileStream.close();
FileStream.open(FilePath, std::fstream::out); //open file in Output mode. This line will delete all data inside the file.
FileStream << BufferString;
FileStream.close();
}
// else --->> do nothing
}
This function does the following steps:
Open the file in input mode
Read all the lines which are not empty
Closes the file
Open the file again in Output mode (deletes all the data inside file)
Put the string into the file
Closes the file.

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.

C++ ofstream : Always write onthe 1st line

I would like to know how could I write always to the first line of a file.
I have numbers to share via a text file to another soft, and I want to write those numbers periodically on the first line.
Thanks.
eo
If you want to completely rewrite the file, discarding it's contents then simply use trunc mode. However, if there is any other content that you want to preserve then the easiest way would be to read the file into memory, change the first line and write everything back. I think it wouldn't be possible to change the first line directly unless you are overwriting the same amount of characters.
Look at this two functions:
ostream& seekp ( streampos pos );
ostream& seekp ( streamoff off, ios_bas:seekdir dir );
maybe this solves your problem
ofstream out("foo.txt");
out << "foo";
out << "\r" << "bar";
this will leave a file with only bar in it.
2nd method:
if the file only contains one line you could open it with ofstream::trunc and close it after each write
If the file is not massive then you could write a new new file copying across each line except for the custom first line. Then afterwards replace the original.
void ReplaceFirstLine(string filename)
{
ifstream infile;
ofstream outfile;
infile.open(filename.c_str(), ios_base::in);
outfile.open("tempname.txt", ios_base::out);
bool first = true;
string s;
while (getline(infile, s, '\n'))
{
if (first)
outfile << "my new first line\n";
else
outfile << s << endl;
first = false;
}
infile.close();
outfile.close();
::CopyFileA("tempname.txt", filename.c_str(), FALSE); // or Linux equivalent
}