str.find member function error - c++

I'm having trouble understanding why my code isn't changing the results of the output file. I tried using the "find" member function to check for the incorrect operators, but it doesn't seem change the results. How would I check to see if a string contains the string I'm looking for, then replace it?
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
void input(ifstream& inputfile, ofstream& outputfile, string& cpp);
void edit(ifstream& inputfile, ofstream& outputfile, string& line);
int main()
{
ifstream inputfile;
ofstream outputfile;
string line, cpp;
input(inputfile,outputfile,cpp);
edit(inputfile, outputfile, line);
}
void input(ifstream& inputfile, ofstream& outputfile, string& cpp)
{
cout << "Enter a cpp file to modify" << endl;
cin >> cpp;
cout << endl;
inputfile.open(cpp.c_str());
if (inputfile.fail())
{
cout << "File opening failed,did you enter your file name correctly?" << endl;
exit(1);
}
outputfile.open("cpp.txt");
}
void edit(ifstream& inputfile, ofstream& outputfile, string& line)
{
string a = "cin <<";
string b = "cout >>";
getline(inputfile,line);
while (! inputfile.eof())
{
line.find(a);
if (line == a)
{
outputfile << "cin >>";
}
line.find(b);
if (line == b)
{
outputfile << "cout >>";
}
else
outputfile << line << endl;
getline(inputfile,line);
}
}

I think you are intention is:
if (line.find(a) != string::npos)
{
outputfile << "cin >>";
}
if (line.find(b) != string::npos)
{
outputfile << "cout >>";
}

std::string::find() doesn't change the string is called with. It tries to find the string or character posted as an argument and returns the position of the character found. All you have to do is check if the return value it doesn't equal std::string::npos, which is a value which means the substring wasn't found:
if (line.find(a) != std::string::npos) {
...
}
else if (line.find(b) != std::string::npos) {
...
}
Also, while (!eof()) is generally seen as a bad programming practice. Perform the input within the loop parameters instead:
while (std::getline(inputfile, line)) {
if (line.find(a) != std::string::npos) {
outputfile << "cin >>";
}
else if (line.find(b) != std::string::npos) {
outputfile << "cout <<";
}
else
outputfile << line << std::endl;
}

find() searches the string for the specified substring and then returns its position if found, it does not modify the string being searched. You are ignoring the return value of find(). Try this instead:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
void input(ifstream& inputfile, ofstream& outputfile, string& cpp);
void edit(ifstream& inputfile, ofstream& outputfile, string& line);
int main()
{
ifstream inputfile;
ofstream outputfile;
string line, cpp;
input(inputfile,outputfile,cpp);
edit(inputfile, outputfile, line);
}
void input(ifstream& inputfile, ofstream& outputfile, string& cpp)
{
cout << "Enter a cpp file to modify" << endl;
cin >> cpp;
cout << endl;
inputfile.open(cpp.c_str());
if (!inputfile)
{
cout << "Input file opening failed, did you enter your file name correctly?" << endl;
exit(1);
}
outputfile.open("cpp.txt");
if (!outputfile)
{
cout << "Output file opening failed" << endl;
exit(1);
}
}
void edit(ifstream& inputfile, ofstream& outputfile, string& line)
{
string a = "cin <<";
string b = "cout >>";
while (getline(inputfile,line))
{
if (line.find(a) != std::string::npos)
{
outputfile << "cin >>";
}
else if (line.find(b) != std::string::npos)
{
outputfile << "cout >>";
}
else
outputfile << line << endl;
}
}

Related

How to open and read a file based on user input c++

I have an assignment that wants me to write a program that reads a text file, then outputs a modified version of that file using a version of Ceasar cipher that shifts the characters of the file that the user calls based on the shift amount that they input. For example if my file reads "hi" and they shift it by 1 it should read "ij". But when I run the program it doesnt recognize when I call in1 or out1 and I just get an error message. Can anyone help me figure out what I'm doing wrong or offer any advice on how to move forward? Thank you in advance!
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cctype>
using namespace std;
int main()
{
//Declare user variables
int shift, file1chars = 0;
char filename[25];
ifstream in1;
ofstream out1;
do
{
in1.clear(); //clear status flags
//Prompt user to enter name of input file and amount of shift
cout << "Please enter the name of the input file." << endl;
cout << "Filename: ";
cin >> filename;
//Open file name
in1.open(filename);
//Error message if no file
if (!in1)
cout << "That is not a valid file. Try again\n";
} while (!in1);
do
{
out1.clear(); //clear status flags
//prompt user to input out file
cout << "Please enter the name of the output file." << endl;
cout << "Filename: ";
cin >> filename;
out1.open(filename);
//Error message if no file
if (!out1)
cout << "That is not a valid file. Try again\n";
} while (!out1);
//write some code to the input file
in1 >> "hi"
//write the integers in a different order to the output file
out1 << //idk where to go from here to initiate shift
//prompt user to enter shift
cout << "Please intput the shift amount: ";
cin >> shift;
cout << "Processing complete" << endl;
//Call file (?)
//Tell user file input is complete and is now printing statistics
cout << "\nShifted input file Complete. Now printing statistics " << endl;
//Show statistics for file
cout << "\nStatistics for file: " << filename << endl;
cout << "------------------------------------------------";
//Show characters in file and stats before shift
cout << "\n\nTotal # of characters in file: " << file1chars << endl;
cout << "Statistics before shift: " << endl;
//Show file before shift
//Show user stats after shift
cout << "\nStatistics after shift: " << endl;
//File after shift
//Close files
out1.close();
in1.close();
return 0;
}
Instead of looking at your code for line by line to see where the problem(s) could be, I ask you to think about your requirements and write code that expresses the intent as closely as possible. Create functions that follow the intended functionality.
Get the input file name.
Get the output file name.
Read the contents of the input file.
Transform the contents of the input file to create the output string.
Write the output string to the output file.
In pseudo code,
int main()
{
infile = get_input_filename()
outfile = get_output_filename()
contents = get_file_contents(infile)
output = transform_input(contents)
write_output(outfile, output)
}
Convert that to C++ code:
// Declare the functions.
std::string get_input_filename();
std::string get_output_filename();
std::string get_file_contents(std::string const& infile)
std::string transform_input(std::string const& contents)j
void write_output(std::string const& outfile, std::string const& output);
// Use them in main.
int main()
{
std::string infile = get_input_filename();
std::string outfile = get_output_filename();
std::string contents = get_file_contents(infile);
std::string output = transform_input(contents);
write_output(outfile, output);
}
// Implement the functions.
std::string get_input_filename()
{
std::string filename;
cout << "Please enter the name of the input file." << endl;
cout << "Filename: ";
cin >> filename;
return filename;
}
std::string get_output_filename()
{
std::string filename;
cout << "Please enter the name of the output file." << endl;
cout << "Filename: ";
cin >> filename;
return filename;
}
std::string get_file_contents(std::string const& infile)
{
std::ifstream inf(infile);
std::string contents;
int c;
while ( (c = inf.get()) != EOF )
{
contents += c;
}
return contents;
}
std::string transform_input(std::string const& contents)
{
std::string res;
// Do the needful to transform contents to res.
return res;
}
void write_output(std::string const& outfile, std::string const& output)
{
std::ofstream outf(outfile);
outf.write(output.c_str(), output.size();
}
If you are able to use a class or struct and functions I would propose something like this:
main.cpp
#include <string>
#include <iostream>
#include <fstream>
#include "CaesarShift.h"
int main() {
std::string filename;
std::cout << "Please enter the name of the input file. ";
std::cin >> filename;
std::ifstream fileIn;
std::string text;
fileIn.open( filename );
if ( !fileIn.is_open() ) {
std::cout << "Failed to open file: " << filename << "." << std::endl;
}
fileIn >> text;
fileIn.close();
CaesarText caesarText;
caesarText.addText( text );
std::cout << "Contents of the Caesar Text before peforming a Caesar Shift:\n"
<< caesarText << std::endl;
int amount = 0;
std::cout << "Please enter the amount to shift the text ";
std::cin >> amount;
std::cout << "Now performing the Caesar Shift: " << std::endl;
caesarShift( caesarText, amount );
std::cout << "Caesar Text after performing a Caesar Shift:\n"
<< ceasarText << std::endl;
std::ofstream fileOut;
fileOut.open( std::string( "shifted_" + filename ) );
if ( !fileOut.is_open() ) {
std::cout << "Failed to open shifted_" << filename << std::endl;
}
// Uncomment to print original text to file otherwise only modified text will be printed.
// fileOut << caesarText.originalText() << std::endl;
fileOut << caesarText.shiftedText() << std::endl;
fileOut.close();
system( "PAUSE" );
return 0;
}
CaesarShift.h
#ifndef CAESAR_SHIFT_H
#define CAESAR_SHIFT_H
class CaesarText {
std::string _originalText;
std::string _shiftedText;
public:
caesarText() = default;
explicit CeasarText( const std::string& text ) :
_originalText( text ) {}
void addText( const std::string& text ) {
_originalText = text;
}
std::string originalText() const {
return _originalText;
}
std::string shiftedText() const {
return _shiftedText;
}
friend void caesarShift( caesarText& c, int amount );
friend std::ostream& operator<<( std::ostream& out, const caesarText& ceasarText );
};
#endif // !CAESAR_SHIFT_H
CaesarShift.cpp
#include "CaesarShift.h"
#include <string>
#include <iostream>
#include <algorithm>
// Overloaded ostream operator
std::ostream& operator<<( std::ostream& o, const CaesarText& c ) {
o << "Original Text: " << c._originalText << "\n";
o << "Shifted Text: " << c._shiftedText << "\n";
return o;
}
// public friend function (visible in main) not actually a part of the class
// but performs operations on it.
// To perform the Caesar Shift here are 3 possible variations of implementing the same task.
void caesarShift( Caesar Text& text, int amount ) {
// Bound amount to the number of characters in the alphabet
// the same value used in any of the three variations below.
amount %= 26;
// Older c++ style loop.
/*for ( std::size_t i = 0; i < text._originalText.length(); i++ ) {
char c = text._originalText[i] + amount;
text._shiftedText += c;
}*/
// Modern C++ style loop
/*for ( auto& c : text._originalText ) {
text._shiftedText += c + amount;
}*/
// std::transform( s1.begin, s1.end, back_inserter( s2 ), lamda as predicate );
/*std::transform( text._originalText.begin(), text._originalText.end(),
std::back_inserter( text._shiftedText ),
[amount]( unsigned char c ) -> unsigned char { return c + amount; }
);*/
}
As for the 3 different variations of performing the Caesar Shift you can just uncomment the appropriate block section.

getline reads same line (C++,istream)

I try to find same lines between two text files.
while (getline (texta,str1)){
while (getline (textb,str2)){
cout<<str1<<str2<<endl;
}}
First while working very well but second one just read first part line of text and then quit. I've tried different textes but doesnt work.
If you want to look all code:
void similars(string text1,string text2){
string str1,str2;
ifstream texta(text1.c_str());
ifstream textb(text2.c_str());
if(texta.is_open() && textb.is_open()){
while (getline (texta,str1)){
while (getline (textb,str2){
cout<<str1<<str2<<endl;
}
}
}
else cout << "Unable to open file";
}
don't mix things those shouldn't do
consider this example:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void similars(string text1, string text2)
{
string str1, str2;
ifstream texta(text1.c_str(), ios::in);
ifstream textb(text2.c_str(), ios::in);
cout << "text1: " << endl << endl;
while(!texta.eof())
{
getline (texta, str1);
cout << str1 << endl;
}
cout << endl << endl;
texta.close(); // closing safely the file
cout << "text2: " << endl << endl;
while(!textb.eof())
{
getline (textb, str2, '\n');
cout << str2 << endl;
}
textb.close();
cout << endl;
}
int main()
{
system("color 1f");
string sText1 = "data1.txt";
string sText2 = "data2.txt";
similars(sText1, sText2);
system("pause");
return 0;
}
just create two text files with notepad or any text editor, rename them to "text1.txt", "text2.txt" and put some text in them and save and close. then run the program.

C++ Write sorted contents of vector<string> to file

This currently reads a .txt file and sorts the contents. I'm trying to get it to write those sorted contents of the vector to a file. Currently it only writes one line, how can I can get it to put all lines in the new file? Thank you so much. -Kaiya
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <fstream>
using namespace std;
inline void keep_window_open() {char ch; cin>>ch;}
int main()
{
string line;
ifstream myfile("weblog.txt");
vector<string> fileLines;
//stack overflow example
if (!myfile) //test the file
{
cout << "Unable to open the file" << endl;
return 0;
}
while (getline(myfile, line))
{
fileLines.push_back(line);
//cout << line << '\n';
}
sort(fileLines.begin(), fileLines.end()); //sorting string vector
for (string &s : fileLines)
{
cout << s << " ";
ofstream newfile ("newfile.txt");
newfile << s << " ";
};
return 0;
}
ofstream newfile ("newfile.txt");
for (string &s : fileLines)
{
cout << s << " ";
newfile << s << " ";
};
Creating newfile for every loop iteration overwrites the content of the file, by default.
Either open newfile before the last loop, or open it in append mode within the loop.
It's because you are creating a new file in each iteration of your loop!
ofstream newfile("newfile.txt");
should be written before the loop.
ofstream newfile ("newfile.txt");
for (string &s : fileLines)
{
cout << s << " ";
newfile << s << " ";
};
ofstream newfile ("newfile.txt");
copy(fileLines.begin(), fileLines.end(), ostream_iterator<string>(newfile, " ") );
Here is my complete code that worked, thanks Xiaotian Pei for your help.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <fstream>
using namespace std;
inline void keep_window_open() {char ch; cin>>ch;}
int main()
{
string line;
ifstream myfile("weblog.txt");
vector<string> fileLines;
if (!myfile) //test the file
{
cout << "Unable to open the file" << endl;
return 0;
}
while (getline(myfile, line))
{
fileLines.push_back(line);
}
sort(fileLines.begin(), fileLines.end()); //sorting string vector
ofstream newfile ("newfile.txt"); //write to new file
for (string &s : fileLines)
{
cout << s << " ";
newfile << s << " ";
}
return 0;
}

I/O file stream C++

#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
using namespace std;
int main()
{
string temp;
ifstream inFile;
ofstream outFile;
inFile.open("ZRMK Matched - 010513.txt");
outFile.open("second.txt");
while(!inFile.eof()) {
getline(inFile, temp);
if (temp != "") {
getline(inFile, temp);
outFile << temp;
}
}
cout << "Data Transfer Finished" << endl;
return 0;
}
I'm having difficulty getting this to work. When I execute the program it cycles for awhile and then terminates without finishing -- it doesn't output any lines of text to the output file. Any help would be appreciated.
Are you trying to copy every line?
while(std::getline(inFile, temp)) {
outFile << temp << "\n";
}
Are you trying to copy every non-blank line?
while(std::getline(inFile, temp)) {
if(temp != "")
outFile << temp << "\n";
}
Are you trying to copy every 2nd non-blank line?
int count = 0;
while(std::getline(inFile, temp)) {
if(temp == "")
continue;
count++;
if(count % 2)
outFile << temp << "\n";
}
Are you simply trying to copy the entire file?
outFile << inFile.rdbuf();
You should use a mode to open files : see std::ios_base::openmode
And don't forget to close the streams you open !
You can even try catch your code to understand the problem if an exception occurred.
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
try {
fstream inFile;
fstream outFile;
// open to read
inFile.open("ZRMK Matched - 010513.txt", ios_base::in);
if (!inFile.is_open()) {
cerr << "inFile is not open ! " << endl;
return EXIT_FAILURE;
}
// Open to append
outFile.open("second.txt", ios_base::app);
if (!inFile.is_open()) {
cerr << "inFile is not open ! " << endl;
return EXIT_FAILURE;
}
string line;
while(getline(inFile, line)) {
if (!line.empty()) {
outFile << line << endl;
}
}
if (outFile.is_open()) {
outFile.close(); // Close the stream if it's open
}
if (inFile.is_open()) {
inFile.close(); // Close the stream if open
}
cout << "Data Transfer Finished" << endl;
return EXIT_SUCCESS;
} catch (const exception& e) {
cerr << "Exception occurred : " << e.what() << endl;
}
return EXIT_FAILURE;
}

Checking if word exists in a text file c++

I need to check if a word exists in a dictionary text file, I think I could use strcmp, but I don't actually know how to get a line of text from the document. Here's my current code I'm stuck on.
#include "includes.h"
#include <string>
#include <fstream>
using namespace std;
bool CheckWord(char* str)
{
ifstream file("dictionary.txt");
while (getline(file,s)) {
if (false /* missing code */) {
return true;
}
}
return false;
}
std::string::find does the job.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
bool CheckWord(char* filename, char* search)
{
int offset;
string line;
ifstream Myfile;
Myfile.open (filename);
if (Myfile.is_open())
{
while (!Myfile.eof())
{
getline(Myfile,line);
if ((offset = line.find(search, 0)) != string::npos)
{
cout << "found '" << search << "' in '" << line << "'" << endl;
Myfile.close();
return true;
}
else
{
cout << "Not found" << endl;
}
}
Myfile.close();
}
else
cout << "Unable to open this file." << endl;
return false;
}
int main ()
{
CheckWord("dictionary.txt", "need");
return 0;
}
char aWord[50];
while (file.good()) {
file>>aWord;
if (file.good() && strcmp(aWord, wordToFind) == 0) {
//found word
}
}
You need to read words with the input operator.