How to read text from file itno standard string cpp - c++

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.

Related

editing a file using cpp code without creating a new file

Is it possible to edit text in a file using cpp code. Already there is related question on it, but it doesn't solve my problem. Kindly help me out.
I have given a rough code line on this.
seek() through the file and try to replace the contents with new string from that point till the end of line.
I need the "hello" string be placed and must be the end of line.
like if we have new.txt as
ABCDEFGHIJKLMNOPQRST
If I want the file content to be changed as
ABCDEHELLO
I am getting the file content as
ABCDHELLOJKLMNOPQRST
fstream file("new.txt",fstream::in|fstream::out);
file.open();
while(getline(file,str))
{
if(value==strstr())
{
file.seekp(pos);
str.erase(pos,len);//len specifies the value till end of str
str.replace(pos,6,"hello");
char *d=new char[str.length()+1];
strcpy(d,str.c_str());
file.write(d,strlen(d));
delete [] d;
}
}
If I could copy the file contents to the string, manipulate it, then copy to the new file then it is possible.
Is it possible to change the contents in the same file. If so kindly help me out, I am struck in this. If the replacing string is longer than the one actually existing then this works, but if the replacing string is smaller than the one which is actually existing then I am unable to do.
if you case is only one line in the file you can easily separate the I/O process in two stages. Read the file and get the position of the text. then close the file and reopened as out then write the string you want. Note that this will work if you have one line in the file
check the following code
std::string value = "GFGHHFGHH";
std::string str;
std::fstream file("new.txt", std::ios::in);
std::size_t found;
while (file >> str)
{
found = str.find(value);
if (found != std::string::npos)
{
str.erase(value.length() );
str.replace(found, 6, "hello");
}
}
file.close();
file.open("new.txt", std::ios::out);
file << str;
file.close();
You can do it using system call for sed:
string s="sed -i s/hey/ho/g file0102.txt";
system(s.c_str());

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.

Replace line in txt file c++

I just wondering cause i have a text file containing STATUS:USERID:PASSWORD in accounts.txt
example it would look like this:
OPEN:bob:askmehere:
OPEN:john:askmethere:
LOCK:rob:robmypurse:
i have a user input in my main as such user can login 3x else status will change from OPEN to LOCK
example after 3 tries of john
before:
OPEN:bob:askmehere:
OPEN:john:askmethere:
LOCK:rob:robmypurse:
after:
OPEN:bob:askmehere:
LOCK:john:askmethere:
LOCK:rob:robmypurse:
what i have done is:
void lockUser(Accounts& in){
// Accounts class consist 3 attributes (string userid, string pass, status)
ofstream oFile;
fstream iFile;
string openFile="accounts.txt";
string status, userid, garbage;
Accounts toupdate;
oFile.open(openFile);
iFile.open(openFile);
while(!iFile.eof()){
getline(iFile, status, ':');
getline(iFile, userid, ':');
getline(iFile, garbage, '\n');
if(userid == in.getUserId()){
toupdate.setUserId(in.getuserId());
toupdate.setPassword(in.getPassword());
toupdate.setStatus("LOCK");
break;
}
//here i should update the account.txt how do i do that?
ofile.open(openFile);
ofile<<toupdate.getStatus()<<":"<<toupdate.getUserId()":"<<toupdate.getPassword()<<":"<<endl;
}
There are two common ways to replace or otherwise modify a file. The first and the "classic" way is to read the file, line by line, check for the line(s) that needs to be modified, and write to a temporary file. When you reach the end of the input file you close it, and rename the temporary file as the input file.
The other common way is when the file is relatively small, or you have a lot of memory, is to read it all into memory, do the modification needed, and then write out the contents of the memory to the file. How to store it in memory can be different, like a vector containing lines from the file, or a vector (or other buffer) containing all characters from the file without separation.
Your implementation is flawed because you open the output file (which is the same as the input file) inside the loop. The first problem with this is that the operating system may not allow you to open a file for writing if you already have it open for reading, and as you don't check for failure from opening the files you will not know about this. Another problem is if the operating system allows it, then your call to open will truncate the existing file, causing you to loose all but the very first line.
Simple pseudo-ish code to explain
std::ifstream input_file("your_file");
std::vector<std::string> lines;
std::string input;
while (std::getline(input_file, input))
lines.push_back(input);
for (auto& line : lines)
{
if (line_needs_to_be_modified(line))
modify_line_as_needed(line);
}
input_file.close();
std::ofstream output_file("your_file");
for (auto const& line : lines)
output_file << line << '\n';
Use ReadLine and find the line you wanna replace, and use replace to replace the thing you wanna replace. For example write:
string Example = "Text to find";
openFile="C:\\accounts.txt"; // the path of the file
ReadFile(openFile, Example);
OR
#include <fstream>
#include <iostream>
#include <string>
int main() {
ifstream openFile;
string ExampleText = BOB;
openFile("accounts.txt");
openFile >> ExampleText;
openFile.replace(Example, "Hello");
}

gzstream lib for C++ : corrupted file created

I want to read and write compressed file with my C++ script. For this purpose, I use the gzstream lib. It works fine with a very simple example like this :
string inFile="/path/inputfile.gz";
igzstream inputfile;
ogzstream outputfile("/path/outputfile.gz");
inputfile.open(inFile.c_str());
// Writing from input file to output file
string line;
while(getline(inputfile, line)) {
outputfile << line << endl;
}
But in my C++ script, things are more complicated and my output files are created within a dynamic vector.
For UNcompressed files, this way worked very fine :
string inFile="/path/uncompressedInputFile.ext";
ifstream inputfile;
vector <ofstream *> outfiles(1);
string outputfile="/path/uncompressedOutputFile.ext";
outfiles[1] = new ofstream(outputfile.c_str());
inputfile.open(inFile.c_str());
string line;
while(getline(inputfile, line)) {
*outfiles[1] << line << endl;
}
Now with compressed file, this way produces me corrupted files :
string inFile="/path/compressedFile.gz";
igzstream inputfile;
vector <ogzstream *> outfiles(1);
string outputfile="/path/compressedOutputFile.gz";
outfiles[1] = new ogzstream(outputfile.c_str());
inputfile.open(inFile.c_str());
string line;
while(getline(inputfile, line)) {
*outfiles[1] << line << endl;
}
I got a "compressedOutputFile.gz" in my path, not empty, but when trying to uncompressed it I got "unexpected end of file" which, I guess, means the file is corrupted....
What's wrong with it ? Can anyone please help me ?! :)
In the simple example, the GZip file is closed automatically when the ofstream is destroyed, which flushes its remaining buffer to disk.
In the dynamic example, you're not closing because the object is being created on the heap. In both cases, this could result in the loss of data at the end of the file, depending on the format. Since GZip is compressed, it's more likely to lose more relevant data, resulting in a more obvious failure.
The best solution is to create a vector<unique_ptr<ogzstream> >, which cause it to automatically destroy streams when they go out of scope. The less optimal solution is to remember to manually delete each pointer prior to exiting the function.
Edit: And as a quick note, as pointed out by #doctorlove in the original comments, you need to use the correct index, otherwise you're causing other issues.

Reading a file - won't open

I am trying to open a file in C++ but it seems to be giving me a bit of hassle, here is the code that deals with opening the file so far:
void CreateHistogram(string str_file, vector<HistogramWord> &result) {
string line;
long location;
HistogramWord newWord;
const char * filename = str_file.c_str();
//ifstream myfile (str_file.c_str());
ifstream myfile (filename);
//myfile.open(filename);
if (myfile.is_open()) {
while (myfile.good()) {
getline(myfile, line);
line = clarifyWord(line);
Okay, just for a bit of explanation, HistogramWord is a struct that is defined in the header and from what I have read in the online documentation, the filename has to be of type const char *, so that is what I have done. Converted str_file to be a const char *.
Now, I have tried a few different things which is why some of the code is commented out. When it gets to the line if (myfile.is_open()), it always evaluates to false. Anyone seem to know why?
Thanks,
Brandon
OK IO 101
If you don't give the complete filepath but only the filename then the current working directory will be appended to the filename.
So if your .exe is in C:\temp and you call your program from this directory and your filename is test.txt then the complete filename in this case will be C:\temp\test.txt
This will only work if the .exe and the test.txt are both under C:\temp.
In all other cases it will fail. You could create the absolute path by using win API or the linux equivalent - I don't know what platform you are on.
Now in order to read a succsfully opened file this will suffice :
void CreateHistogram(string str_file, vector<HistogramWord> &result) {
string line;
long location;
HistogramWord newWord;
ifstream myfile (str_file.c_str());
if (myfile.is_open()) {
while (getline(myfile, line)) {
line = clarifyWord(line);
}
else{
//throw exception, print error message etc
throw std::exception(std::string("Couldn't open file : " + str_file).c_str());
}
}
edit : Thanks # Shahbaz
My best guess is that Windows is "hiding extensions for known file types" so the name of the file is actually different than what you have put in windows. For example if it's a .txt file, and you name it test.txt, the actual name would be test.txt.txt which is quite a stupid thing windows does.
To change this, go to My Computer -> Toold -> Folder Options -> And uncheck the box that says "Hide extensions for Known File Types". This is for XP. If you have another windows it should be more or less the same path. If you don't see the toolbar, try ALT+t (tools) or ALT+f (file) to make it appear.
This problem give quite many of us a trouble in the first semester of college.
What fixed it for me was using forward slashes instead of double backslashes in my filepath.
e.g.
inFile.open("path/to/file.txt")
instead of
inFile.open("path\\to\\file.txt")