How can i open multiple files in one run in C++? - c++

Hey I have several Files that I want to read. The user would input what file they want to open on console. And if they want they can change and read another file, they would do so.
This is how i went by doing (this is just rough copy, the code i have is too big will take too long to understand)
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <iomanip>
#include<algorithm>
using namespace std;
int main()
{
string FileName;
string Line;
cout << "Input File Directory To Open :" << endl;
cin >> FileName;
ifstream File;
File.open(FileName);
string Input;
do {
cout << "Enter R to Read Display Data In File Or C to Read Another File Or X To Exit" << endl;
cin >> Input;
if (Input == "R")
{
while (getline(File, Line))
{
cout << Line;
}
}
else if (Input == "C")
{
string FileName2;
cout << "Enter New File Directory To Open: " << endl;
cin >> FileName2;
//? ? ? ?
}
} while (Input != "X");
}
Since it's in do while loop, when user input C and input directory to read another file, so that they can cout new file when they input R next.
My question is how should i overwrite the FileName2 with FileName?
Hope It makes sense Thank you

First close the file that is already open:
File.close();
Then open the new one:
File.open(FileName2);

Both answers keep your idea of an open file handle. However, a better approach is to use RAII. In that case you only register the file name and only open the file when you need it.
int main()
{
std::cout << "Input File Directory To Open :\n";
std::string fileName;
std::cin >> fileName;
while (true) {
std::cout << "Enter R to Read Display Data In File Or C to Read Another File Or X To Exit\n";
std::string input;
std::cin >> input;
if (input == "X") break;
if (input == "R") {
std::ifstream file(filename);
std::string line;
while (std::getline(file, line)) {
std::cout << line;
}
// due to RAII the file will close when the object goes out of scope
} else if (input == "C") {
std::cout << "Enter New File Directory To Open: \n";
std::cin >> fileName;
}
}
}

You don't need a new variable. Simply assign the value to the existing one, close the currently opened file, and then open the new file inside the loop:
...
else if (Input == "C")
{
cout << "Enter New File Directory To Open: " << endl;
cin >> FileName;
File.close();
File.open(FileName);
}
...

Related

How to load data into a vector from a text file that has been created inside the same program. in C++

I want to load data from a Text file that has been created in the same program into a vector of strings. But no line of text is getting pushed into the vector here.
Here First I am reading data from some input file and then doing some operations (Removing extra spaces) on it then I save this file as "intermediate.txt". This intermediate.txt is being created and all the operations that I want to do happen successfully. Finally, I want to read this file into a vector<string> code but it doesn't work. I can't store anything in the vector<string> code. Its size is Zero.
#include <bits/stdc++.h>
using namespace std;
int main()
{
string inputFileName;
cout << "Enter the Input File Name: ";
cin >> inputFileName;
ifstream f1(inputFileName);
ofstream f0("intermediate.txt");
string text_line;
while (getline(f1, text_line))
{
string word;
istringstream text_stream(text_line);
while (text_stream >> word)
{
f0 << word << " ";
}
f0 << "\n";
}
f0.close()
ifstream file("intermediate.txt");
vector<string> code;
string line;
while (getline(file, line, '\n'))
{
code.push_back(line);
}
for (auto it : code)
{
cout << it << "\n";
}
}
Here's a mini-code review:
#include <bits/stdc++.h> // Don't do this; doesn't even compile for me
using namespace std; // Don't do this either
int main()
{
string inputFileName;
cout << "Enter the Input File Name: ";
cin >> inputFileName;
ifstream f1(inputFileName); // Bad name
ofstream f0("intermediate.txt"); // Bad name
// You never check that you successfully opened *any* files.
string text_line;
/*
* You don't describe why this is necessary, can a line not be read and
* written as-is? Is it already a line of space-separated variables?
*
* In any case, this is where you already have the words; so store them in
* the vector here as well.
*/
while (getline(f1, text_line))
{
string word;
istringstream text_stream(text_line);
while (text_stream >> word)
{
f0 << word << " ";
}
f0 << "\n";
}
f0.close() // Forgot your semi-colon
// Left f1 open, that's bad practice
ifstream file("intermediate.txt");
vector<string> code;
string line;
/*
* I would hope you felt that reading from a file, writing to a new file,
* closing both files, opening the new file, and reading from the new file
* into the vector was wasteful.
*/
while (getline(file, line, '\n'))
{
code.push_back(line);
}
for (auto it : code)
{
cout << it << "\n";
}
}
The most immediate issue with your original question was that you tried to open the same file in two different streams. The second time, the file failed to open, but because you never check if you actually opened the file, you assumed everything worked fine, but it didn't, which brought you here.
However, there is a better way.
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
int main() {
std::string inputFileName;
std::cout << "Enter the Input File Name: ";
std::cin >> inputFileName;
// Always check that you successuflly opened the file.
std::ifstream fin(inputFileName);
if (!fin) {
std::cerr << "Error opening: " << inputFileName << ". Exiting...\n";
return 1;
}
std::ofstream fout("intermediate.txt");
if (!fout) {
std::cerr << "Error opening: intermediate.txt. Exiting...\n";
return 2;
}
std::vector<std::string> code;
std::string text_line;
while (std::getline(fin, text_line)) // You've read the line
{
std::string word;
std::istringstream text_stream(text_line);
while (text_stream >> word) {
fout << word << " ";
}
fout << "\n";
code.push_back(text_line); // Just store it while you have it
}
fin.close(); // Best practice is to close a file as soon as you're done
fout.close(); // with it. Don't hog resources.
for (const auto& it : code) // Avoid making copies
{
std::cout << it << "\n";
}
}
The while loop, where you read the lines that you want to store in the vector, now writes to your file and stores the lines into the vector. We also now check whether we successfully opened files, and we close the file streams as soon as we're done with the file so as to not keep it locked for no good reason.
A good next step for improving this program a bit more would be to avoid asking the user for a file name. Instead, take it as an argument to main(). That way, someone only has to type ./a.out input.txt on the command line and the program will do the job automatically.

No matching function for call when reading file

I'm getting an error when I'm trying to open my file and perform a read operation on my second file. I'm not sure what went wrong.
error: no matching function for call to β€˜std::basic_fstream<char>::open(std::string&)’
file.open(filename);
int main()
{
DoublyLinkedBag<string> dictionary;
fstream file;
string word;
file.open("dictionary.txt", ios::in); // open a file to perform read operation using file object
if (file.is_open()) // check whether file is open
{
while (file >> word)
{
dictionary.add(word);
}
}
string filename;
string words;
cout << "Enter the name of the file that contains words to check:" << endl;
cin >> filename;
file.open(filename);
if (file.is_open())
{
while (file >> words)
{
if (!dictionary.contains(words))
{
cout << "The following words in the file " << filename << " are not spelled correctly:" << endl;
cout << words << endl;
cout << "Thanks for using the spell checker system." << endl;
}
}
}
file.close();
}
The error message is self-explanatory. open() in the version of C++ you are compiling for does not accept a std::string as a parameter. That overload was added in C++11.
So, either update your project to compile for C++11 or later, or else for older versions you will have to use this instead:
file.open(filename.c_str());

Rename and remove function for the txt file is not working c++

I know this is asked a lot, but I am spending hours to solve this problem. I am trying to edit txt file by replacing names. I copied my datas to the temp.txt file and when I enter the inputs, temp file does the job and changing the word. But the functions which are remove and rename are not working. My code is below:
string search_string;
string replace_string;
ofstream file;
file.open("temp.txt"); //opening file
cout<<"Enter the word you want to change: ";
cin>>search_string;
cout<<"Enter the new word: ";
cin>>replace_string;
string inbuf;
fstream input_file("musics.txt", ios::in);
ofstream output_file("temp.txt");
while (!input_file.eof())
{
getline(input_file, inbuf);
int spot = inbuf.find(search_string);
if(spot >= 0)
{
'this is the replacing part'
}
output_file << inbuf << endl;
remove("musics.txt");
file.close();
rename("temp.txt", "musics.txt");
}
You have 2 main problems.
You open the output file twice.
You must close all files before you do file operations
Especially the 2nd topic is causing the trouble.
Here a working solution:
#include <iostream>
#include <cstdio>
#include <fstream>
#include <regex>
// The filenames
const std::string musicFileName{ "music.txt" };
const std::string tempFileName{ "temp.txt" };
int main() {
// Open a new scope, so that the file streams
// will be closed automatically by the destructor
{
// Open the source file
std::ifstream sourceFile(musicFileName);
// Check, if it could be opened
if (sourceFile) {
// Source file is open, now open the temp file
std::ofstream tempFile(tempFileName);
// Check, if the tempfile could be opened
if (tempFile) {
// Both files are open, get the search and replace strings
std::string searchString;
std::string replaceString;
std::cout << "Enter the word you want to change: ";
std::cin >> searchString;
std::cout << "Enter the new word: ";
std::cin >> replaceString;
// Now read all lines from source file
std::string textLine{};
while (std::getline(sourceFile, textLine)) {
// Replace the text and write it to the destination file
tempFile << std::regex_replace(textLine, std::regex(searchString), replaceString) << "\n";
}
}
else {
std::cerr << "Could not open '" << tempFileName << "'\n";
}
} // <-- This will close the temp file
else {
std::cerr << "Could not open '" << musicFileName << "'\n";
}
} // <-- This will close the source file
// Remove and rename
std::remove(musicFileName.c_str());
std::rename(tempFileName.c_str(), musicFileName.c_str());
return 0;
}

Having trouble validating a file over and over again

One of the things my program needs to do is validate a file using the isValid function entered by user and it will keep doing this until exit is entered and if I enter nothing but valid file names there are no problems. But when I enter an invalid file name followed by a valid file name it still says the file is invalid and I cannot figure out why and I have tried debugging it and what not and still cannot find the problem. Any help would be greatly appreciated!
# include <iostream>
#include <string>
#include<fstream>
#include<vector>
using namespace std;
void Open_file(string name)
{
ifstream my_file;
my_file.open(name.c_str());
}
bool isValid(ifstream& file, string name)
{
if ((name.substr(name.length() - 4)) != (".htm"))
{
return false;
}
cout << file << endl;
if (file.good())
{
return true;
}
else
{
return false;
}
}
string File_title(ifstream& my_file)
{
string title;
string line;
size_t first_title;
size_t second_title;
string str;
while((getline(my_file,line)))
{
str = str + line;
}
first_title = str.find("<title>");
second_title = str.find("</title>");
title = str.substr(first_title + 7, (second_title) - (first_title + 7));
return title;
}
void Output_function(ifstream& my_file)
{
string line;
ifstream MyFile("titles.txt");
string g = File_title(my_file);
while(getline(MyFile, line))
{
if((g == line))
{
return;
}
}
ofstream out_title("titles.txt", fstream::app);
out_title << g << endl ;
}
void Clear_file()
{
ofstream out_title("titles.txt");
out_title << "" << endl;
}
int main()
{
string file_name;
while (file_name != "exit")
{
cout <<"please enter a HTML file name or hit 'exit' to quit and " << endl;
cout << "if you want to clear file please enter 'clear': ";
getline(cin,file_name);
ifstream my_file(file_name.c_str());
cin.ignore(256, '\n');
if(file_name == "clear")
{
Clear_file();
break;
}
while ((isValid(my_file, file_name) == false))
{
cin.clear();
cout <<"Invalid file name, please enter a valid file name: ";
getline(cin,file_name);
ifstream my_file(file_name.c_str());
}
Open_file(file_name);
Output_function(my_file);
my_file.close();
}
}
ifstream my_file(file_name.c_str());
This doesn't replace the my_file you'd already created in an outer scope. It just makes a new local variable that lives for like a nanosecond.
You'll have to close then re-open the existing my_file, being sure to reset its error flags too.
The logic you are using to exit the loop is flawed.
You need to check the value of file_name right after it is entered, not after it is processed in the while loop once.
You need to use something along the lines of:
while ((file_name = get_file_name()) != "exit")
{
...
}
where
std::string get_file_name()
{
std::string file_name;
cout <<"please enter a HTML file name or hit 'exit' to quit and " << endl;
cout << "if you want to clear file please enter 'clear': ";
getline(cin,file_name);
return file_name;
}
Other improvements:
The call to cin.ignore() is going to be a problem line since std::getline does not leave the newline character in the input stream. You'll have to type Enter one more time. You should remove it.
You don't need the cin.clear() line. You need cin.clear() only if an error was detected in reading from the stream -- such as when using cin >> var; when the input stream did not have the right data suitable for var.
You don't need to open the file if the file is not valid.
You don't need multiple lines ifstream my_file(file_name.c_str());. You only need it once, just before the call to Output_function(my_file).
You don't need to explicitly call my_file.close(). The file will be closed and the end of the scope.
Here's a simplified version of main.
int main()
{
string file_name;
while ((file_name = get_file_name()) != "exit")
{
if(file_name == "clear")
{
Clear_file();
break;
}
while ( isValid(my_file, file_name) == false )
{
cout <<"Invalid file name, please enter a valid file name: ";
getline(cin,file_name);
}
Open_file(file_name);
ifstream my_file(file_name.c_str());
Output_function(my_file);
}
}

Writing to a file with fstream and cstring

#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char filename[20] = "filename";
char userInput;
ofstream myFile;
cout << "Enter filename: ";
cin.getline(filename, sizeof(filename));
myFile.open(filename);
if(myFile.fail())
{
cout << "Error opening file: "
<< filename << "\n";
return 1;
}
cout << "Add text to the file: ";
cin.get(userInput);
while(cin.good() && userInput)
{
myFile.put(userInput);
cin.get(userInput);
}
myFile.close();
return 0;
}
Im having trouble terminating the input without force quiting it(It still writes to the file).
This is what I am supposed to do
Receives a line of input from the user, then outputs that
line to the given file. This will continue until the line input
by the user is β€œ-1” which indicates, the end of input.
however I cannot work out the -1 part. Any help would be greatly appreciated everything else seems to work.
You're making things a bit more complicated than they need to be. Why C strings instead of std::string, for example? Using the right (standard-provided) classes generally leads to shorter, simpler and easier-to-understand code. Try something like this for starters:
int main()
{
std::string filename;
std::cout << "Enter filename" << std::endl;
std::cin >> filename;
std::ofstream file{filename};
std::string line;
while (std::cin >> line) {
if (line == "-1") {
break;
}
file << line;
}
}
First of all, the assignment asks to read a line from the user, character-wise input by get() shouldn't be the function to use. Use the member function getline() as you did to recieve the file name and use a comparison function to check against -1:
for (char line[20]; std::cin.getline(line, sizeof line) && std::cin.gcount(); )
{
if (strncmp(line, "-1", std::cin.gcount()) == 0)
break;
myFile.write(line, std::cin.gcount());
}