How to write in the same file C++ - c++

I need to delete all the occurencies of a string in a file.
I receive the text as a string and erase every occurencies.
After I deleted all the occurencies i don't know how to save the string back to the file.
I've tried to close the file and wit ofstream to write in it but it didn't work.
#include <iostream>
#include <fstream>
#include <string>
int main () {
std::string file_contents = "";
std::ifstream myfile ("text.txt");
char ch;
if (myfile.is_open())
{
// READ FILE CONTENTS AS STRING
while ( myfile >> std::noskipws >> ch)
{
file_contents += ch;
}
// DISPLAY STRING
std::cout << file_contents << '\n';
// GET WORD TO BE DELETED
std::string word;
std::cout << "Please enter word to be deleted: ";
std::cin >> word;
std::string::size_type found;
std::string new_text;
//DELETE WORD FROM STRING
bool ok=0;
do{
found = file_contents.find(word);
ok=1;
if (found!=std::string::npos)
{
std::cout << word << " found at: " << found << '\n';
file_contents.erase(found, word.length());
std::cout << file_contents << '\n';
}
else
ok==0;
new_text=file_contents;
}while(ok==1);
myfile.close();
}
else std::cout << "Unable to open file";
return 0;
}

Okay so you must close ifstream instance before proceeding to write to the file again.
After closing the file, modify the content and then open the same file for write using ofstream and simply write the content.
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string file_contents = "";
std::ifstream myfile("text.txt");
char ch;
if (myfile.is_open())
{
// READ FILE CONTENTS AS STRING
while (myfile >> std::noskipws >> ch)
{
file_contents += ch;
}
myfile.close();
}
else {
std::cout << "Unable to open file";
return -1; // no need to continue if can't read it
}
// DISPLAY STRING
std::cout << file_contents << '\n';
// GET WORD TO BE DELETED
std::string word;
std::cout << "Please enter word to be deleted: ";
std::cin >> word;
//DELETE WORD FROM STRING
size_t found;
while ((found = file_contents.find(word)) != file_contents.npos)
{
std::cout << word << " found at: " << found << '\n';
file_contents.erase(found, word.length());
std::cout << file_contents << '\n';
}
// this will open in text mode and will replace all existing content
std::ofstream out("text.txt");
if (out.is_open()) {
out << file_contents;
out.close();
}
else {
std::cout << "Unable to open file for writing.\n";
return -2; // for failure to open for write
}
return 0;
}
Note: the loop you had went infinitely when I tried to execute it, I had to change it to the code shown above. Also, new_text is completely unnecessary, why have it?

The simpliest way is first to open as input stream. When finish open as output stream to write. It is not the only way you can do that.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
std::string file_contents = "";
{
std::ifstream myfile ("text.txt");
if (! myfile.is_open())
{
else std::cout << "Unable to open file";
return 1;
}
// READ FILE CONTENTS AS STRING
char ch;
while ( myfile >> std::noskipws >> ch) file_contents += ch;
myfile.close();
}
{
std::string word;
std::cin >> word; // GET WORD TO BE DELETED
std::string::size_type found;
while((found = file_contents.find(word))!=std::string::npos)
file_contents.erase(found, word.length());
std::ofstream myfile ("text.txt");
myfile << file_contents<< std::flush;
myfile.close();
}
return 0;
}

Related

Read input from a file, capitalize first letter, make every other letter lowercase, and output into a separate file

I am supposed to ask the user for two file names (input and output files). The contents from the input file should be read and the first letter of each sentence should be made uppercase while every other letter should be made lowercase. The results should then be stored in the output file.
I am aware that there are ways of using the toupper and tolower functions that include pointers, arrays, or even ASCII values of chars but I am trying to get this code to work by using if/else and while statements, as well as boolean statements. I have had various results ranging from all the letters being capitalized to none of the letters being capitalized however, I think right now I am on the right track with the code and am just overlooking the way I am incrementing through the characters causing the code to not capitalize after a period and a space.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string input_file; // To hold input file name
string output_File; // To hold output file name
char ch; // To hold character
fstream inputFile;
fstream outputFile;
bool new_sentence = true;
cout << "Enter input file name: " << endl;
cin >> input_file;
cout << "Enter output file name: " << endl;
cin >> output_File;
outputFile.open(output_File, ios::out);
inputFile.open(input_file, ios::in);
if (inputFile) {
while (inputFile.get(ch)) {
if (isprint(ch)) {
if (new_sentence) {
outputFile.put(toupper(ch));
}
else {
outputFile.put(tolower(ch));
}
new_sentence = false;
}
else {
if (ch == '.') {
new_sentence = true;
outputFile.put(ch);
}
}
}
inputFile.close();
outputFile.close();
}
else {
cout << "Cannot open file(s)." << endl;
}
cout << "\nFile conversion complete." << endl;
return 0;
}
With my current code I am able to capitalize the first letter of the first sentence and make every other letter lowercase. I am able to store and show the results in the output file. My issue is that the first letter of every other sentence after the first one won't change to uppercase. This makes me think the issue is in this part of the code:
if (new_sentence)
{
outputFile.put(toupper(ch));
}
else
{
outputFile.put(tolower(ch));
}
Am I missing something here?
You have a minor logical error.
You first need to check, if the character is a period. This state you need to remember. If then a next character isalpha, then we check, if recently the newsentence flag has been set. In this case, and only in this case, we reset the new sentence flag and convert the character to uppercase.
All other alpha characters will be converted to lowercase. Other charcaters will not be converted.
In your solution you always reset the newsentence flag. Even, if the next print character is a space (Which is most liekly the case).
Please see updated solution:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string input_file; // To hold input file name
string output_File; // To hold output file name
char ch; // To hold character
fstream inputFile;
fstream outputFile;
bool new_sentence = true;
cout << "Enter input file name: " << endl;
cin >> input_file;
cout << "Enter output file name: " << endl;
cin >> output_File;
outputFile.open(output_File, ios::out);
inputFile.open(input_file, ios::in);
if (inputFile) {
while (inputFile.get(ch)) {
if (ch == '.') {
new_sentence = true;
}
if (isalpha(ch)) {
if (new_sentence) {
ch = toupper(ch);
new_sentence = false;
}
else {
ch = tolower(ch);
}
}
outputFile.put(ch);
}
inputFile.close();
outputFile.close();
}
else {
cout << "Cannot open file(s)." << endl;
}
cout << "\nFile conversion complete." << endl;
return 0;
}
And then, please see some further improvements:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
int main() {
// Will hold the input and output filename
std::string filename;
// This is our flag to indicate that a new sentence will come
bool newSentence = true;
// Get input filename
std::cout << "Enter input file name: " << "\n";
std::cin >> filename;
// And try to open the file
std::ifstream inFile(filename);
std::cout << "Enter output file name: " << "\n";
std::cin >> filename;
// And try to open the file
std::ofstream outFile(filename);
// Only convert, if the input and output file could be opened
if (inFile && outFile) {
char ch;
while (inFile.get(ch)) {
if (ch == '.') {
newSentence = true;
}
if (isalpha(ch)) {
if (newSentence) {
ch = toupper(ch);
newSentence = false;
}
else {
ch = tolower(ch);
}
}
outFile.put(ch);
}
}
else {
std::cout << "Cannot open file(s)\n";
}
std::cout << "\nFile conversion program complete\n";
return 0;
}
And the full blown "C++ with algorithm" solution. Here the conversion, or transformation is done in one statement
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <algorithm>
#include <iterator>
int main() {
// Will hold the input and output filename
std::string filename;
// Get input filename
std::cout << "Enter input file name: " << "\n";
std::cin >> filename;
// And try to open the file
std::ifstream inFile(filename);
std::cout << "Enter output file name: " << "\n";
std::cin >> filename;
// And try to open the file
std::ofstream outFile(filename);
// Only convert, if the input and output file could be opened
if (inFile && outFile) {
// Do the conversion
std::transform(
std::istreambuf_iterator<char>(inFile),
std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>(outFile),
[newSentence = true](char c) mutable {
if (c == '.') newSentence = true;
if (std::isalpha(c))
if (newSentence) {
newSentence = false;
c = std::toupper(c); }
else c = std::tolower(c);
return c;
}
);
}
else {
std::cout << "Cannot open file(s)\n";
}
std::cout << "\nFile conversion program complete\n";
return 0;
}
But if the last solution adds additional value? I am not sure . . .
This part of your code should be changed:
// if (isprint(ch)) {
if (ch != '.') {
if (new_sentence) {
outputFile.put(toupper(ch));
}
else {
outputFile.put(tolower(ch));
}
new_sentence = false;
}
else {
new_sentence = true;
outputFile.put(ch);
}
std::isprint() only checks if the character is printable.
Full code:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string input_file; // To hold input file name
string output_File; // To hold output file name
char ch; // To hold character
fstream inputFile;
fstream outputFile;
bool new_sentence = true;
cout << "Enter input file name: " << endl;
cin >> input_file;
cout << "Enter output file name: " << endl;
cin >> output_File;
outputFile.open(output_File, ios::out);
inputFile.open(input_file, ios::in);
if (inputFile) {
while (inputFile.get(ch)) {
if (ch != '.') {
if (new_sentence) {
outputFile.put(toupper(ch));
}
else {
outputFile.put(tolower(ch));
}
new_sentence = false;
}
else {
new_sentence = true;
outputFile.put(ch);
}
}
inputFile.close();
outputFile.close();
}
else {
cout << "Cannot open file(s)." << endl;
}
cout << "\nFile conversion complete." << endl;
return 0;
}

C++ ifstream error using string as opening file path

I get this error when I try running the program.What might be the problem as the code is correct as far as I can see.
Here is the error
std::basic_fstream::basic_fstream(std::string&, const openmode&)'
Here is the code
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string fileName;
int frequencyArray[26];
char character;
for (int i = 0; i < 26; i++)
frequencyArray[i] = 0;
cout << "Please enter the name of file: ";
getline(cin, fileName);
fstream inFile(fileName, fstream::in); // to read the file
if (inFile.is_open())
{
while (inFile >> noskipws >> character)
{
// if alphabet
if (isalpha(character))
{
frequencyArray[(int)toupper(character) - 65]++;
}
}
inFile.close();
cout << "Letter frequencies are as: " << endl;
for (int i = 0; i < 26; i++)
{
cout << (char)(i + 65) << " = " << frequencyArray[i] << endl;
}
}
else
{
cout << "Invalid File. Exiting...";
}
return 0;
}
You could change
fstream inFile(fileName, fstream::in);
to
fstream inFile(fileName.c_str(), fstream::in);
Although C++11 defines a std::fstream constructor that accepts a std::string as input, Microsoft's implementation of std::fstream apparently does not:
https://msdn.microsoft.com/en-us/library/a33ahe62.aspx#basic_fstream__basic_fstream
You will have to use the std::string::c_str() method to pass the filename:
fstream inFile(fileName.c_str(), fstream::in);
That being said, consider using std::ifstream instead:
ifstream inFile(fileName.c_str());

Reading line by line and fetch word from line in C++

string line;
string filename;
cout << "Please enter filename :" << endl;
cin >> filename;
ifstream myfile(filename);
/*cout << "Please enter the name of file that you write results : "<< endl;
cin >> wfile; */
if(myfile.is_open())
{
while(getline(myfile,line))
{
convert(line);
}
//getline(myfile,line);
//pushintoVector(line,buffer);
}
else
{
cout << "Error : File could not be opened" << endl;
}
try{
myfile.close();
myFile.close();
}catch(exception &e1)
{
cout << endl;
}
//system("PAUSE");
return 0;
After that i want to send current line to another function like:
void convert(string lines)
{
myFile.open("yazici.txt");
string buf;
string convertingnum;
istringstream ss(lines);
while(ss >> buf)
{
So how can i read word from a line and change it according to if-else structure and write it another file.Edit: Also is there a function or method to determine line length ?
Open the output file at the same time you open the input file.
Pass the output stream as an argument to convert instead of opening the file every time in the function.
Use better names than myfile and myFile.
ifstream inputFile(filename);
ofstream outputFile("yazici.txt");
if(inputFile.is_open())
{
while(getline(inputFile,line))
{
convert(outputFile, line);
}
}
and ...
void convert(std::ostream& outputFile,
string lines)
{
string buf;
string convertingnum;
istringstream ss(lines);
while(ss >> buf)
{
outputFile << buf << std::endl; //???
}
}

How to read words instead of characters?

I am currently trying to read a bunch of words from a .txt document and can only manage to read the characters and display them yet. I'd like to do the same but with whole words.
My code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream infile("banned.txt");
if (!infile)
{
cout << "ERROR: ";
cout << "Can't open input file\n";
}
infile >> noskipws;
while (!infile.eof())
{
char ch;
infile >> ch;
// Useful to check that the read isn't the end of file
// - this stops an extra character being output at the end of the loop
if (!infile.eof())
{
cout << ch << endl;
}
}
system("pause");
}
Change char ch; to std::string word; and infile >> ch; to infile >> word; and you're done. Or even better do the loop like this:
std::string word;
while (infile >> word)
{
cout << word << endl;
}

ifstream getline issue (it only reads the first line)

Something is definitely wrong with my loop because after reading and executing the first line the programs ends.
if (infile.is_open())
{
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
cout<< "Output filename: ";
cin>>filename;
outfile.open(filename.c_str());
while(getline(infile,input))
{
string output = "";
for(int x = 0; x < input.length(); x++)
output += cipher(input[x]);
cout<<output<<endl;
outfile<<output;
}
}
Any suggestions on how to make this work?
EDIT
Followed the suggestions and got this:
if (infile.is_open()) {
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
if (!infile.is_open())
{
std::cout << "Failed to open the input file." << std::endl;
return -1;
}
cout<< "Output filename: ";
cin>>filename;
outfile.open(ofilename.c_str());
if (!outfile.is_open())
{
std::cout << "Failed to open the output file." << std::endl;
return -1;
}
while(getline(infile,line)){
string output = "";
for(int x = 0; x < input.length(); x++) {
output += cipher(input[x]);
}
}
BUT it still reads only the first line...everything else is working perfectly fine....just can't read anything beyond the first line..
It seems that you misunderstood the point of the fstream's is_open() method, since this code:
if (infile.is_open())
{
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
...
}
checks whether the infile has been successfully opened (i.e. if either a previous call to member open succeeded or if the object was successfully constructed using the parameterized constructor,
and close has not been called since) and in case it is open it retrieves the name of the input file from cin and opens the file.
Good start would be the program that reads from the input file line by line and writes these lines to the output file without processing them:
// retrieve the name of the input file and open it:
cout << "Input filename: ";
cin>>filename;
infile.open(filename.c_str());
if (!infile.is_open())
{
std::cout << "Failed to open the input file." << std::endl;
return -1;
}
// retrieve the name of the output file and open it:
cout << "Output filename: ";
cin >> filename;
outfile.open(filename.c_str());
if (!outfile.is_open())
{
std::cout << "Failed to open the output file." << std::endl;
return -1;
}
std::string line;
while(getline(infile,line))
{
std::cout << line << std::endl;
outfile << line;
}
So I suggest this.
Write char cipher(char ch) to return enciphered input for anything. if you don't want to encipher whitespace, then don't. But always return the enciphered character or unmodifed character.
Use std::transform , std::istream_iterator , and std::ostream_iterator to transform your input and output files.
Check your file states at the correct times.
An example appears below:
#include <iostream>
#include <fstream>
#include <iteraor>
#include <string>
using namespace std;
char cipher(char ch)
{
if (std::isalpha(ch))
{
// TODO: change ch to whatever you want here.
}
// but always return it, whether you changed it or not.
return ch;
}
int main()
{
int res = EXIT_SUCCESS;
string in_filename, out_filename;
cout << "Input filename: ";
cin >> in_filename;
cout << "Output filename: ";
cin >> out_filename;
// don't skip whitespace
ifstream infile(in_filename);
ofstream outfile(out_filename);
if ((infile >> noskipws) && outfile)
{
std::transform(istream_iterator<char>(infile),
istream_iterator<char>(),
ostream_iterator<char>(outfile),
cipher);
}
else
{
perror("Failed to open files.");
res = EXIT_FAILURE;
}
return res;
}