#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void read();
int main() {
read();
return 0;
}
void read () {
string file("");
string nameOfFile("");
cin >> nameOfFile;
ifstream in (nameOfFile);
while ( !in.eof() ) {
getline(in, file);
cout << file;
cout << endl;
}
cout << file;
in.close();
}
How come this isn't working, I'm trying to make it so i can type in which file i want to read?
I'm really new to C++, sorry if this is an obvious fix.
You have to change
ifstream in (nameOfFile);
with
ifstream in (nameOfFile.c_str());
because the default constructor for ifstream does not accept a std::string as an argument, it needs a char *. Hence, use the function std::string::c_str() to convert a std::string into a char *.
A little feedback:
void read () {
string file(""); // you don't need the ("") bit; empty by default,
// and "file" is a terrible choice of identifier as
// it sounds more like an ifstream than a string
// used to hold one line from the file.
// I tend to use "string line;" for this.
string nameOfFile(""); // ditto
cin >> nameOfFile; // you should test for success of input, like this:
// if (!cin >> nameOfFile) {
// std::cerr << "error reading filename from stdin\n";
// exit(1);
// }
ifstream in (nameOfFile); // test for success getting file open like this:
// if (ifstream in(nameofFile))
// {
while ( !in.eof() ) { // NEVER check eof before attempting input, instead:
getline(in, file); // while (getline(in, file))
cout << file; // cout << file << endl; // can "chain"
cout << endl; // }
// else
// std::cerr << "couldn't open " << nameOfFile
// << '\n';
} // no need for extra cout nor explicit close, as
cout << file; // the ifstream destructor closes anyway.
in.close();
}
You need to open the ifstream usign in.open(), and hendle the case where file does not exist as well. here is the function:
void read() {
string file("");
string fileContent = "";
string nameOfFile("");
cin >> nameOfFile;
ifstream in(nameOfFile.c_str());
in.open(nameOfFile, ios::in);
if (in){
while (!in.eof()) {
getline(in, file);
fileContent += file;
}
cout << fileContent;
in.close();
}
else {
cout << "Could not open file.";
}
}
Related
Can someone tell me what is wrong in this code? Particularly the function longestLine.
When I run the code without that funcion (only using the inside of it) the program runs with no problems, but when I do it with the function it does not compile.
I dont understand the error the compiler gives but I think it has something to do with the argument of the funcion.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string longestLine(ifstream infile);
string promptUserForFile(ifstream & infile, string prompt="");
int main() {
ifstream infile;
promptUserForFile(infile);
cout << "The longest line of the file is: " << endl;
cout << longestLine(infile);
return 0;
}
string promptUserForFile(ifstream & infile, string prompt) {
while (true) {
cout << prompt;
string filename;
getline(cin, filename);
infile.open(filename.c_str());
if (!infile.fail())
return filename;
infile.clear();
cout << "Unable to open that file. Try again." << endl;
if (prompt == "")
prompt = "Input file: ";
}
}
string longestLine(ifstream infile) {
int length = 0;
string longest_line;
string line;
while (getline(infile, line)) {
if (line.length() > length) {
length = line.length();
longest_line=line;
}
}
return longest_line;
}
I think you should pass ifstream by reference
string longestLine(ifstream& infile);
ifstream derive from ios_base, the copy constructor of stream is deleted: because streams are not copyable.
If you pass ifstream by value, the compiler will try to call the copy constructor of ifstream when you call longestLine, the compiler will definitely complain this error.
cppreference: basic_ifstream
I want to take more than one line from the data.txt file. I am able to take only the first one. I tried using while loop but it seems that I don't know how to use it in this case.
Edited with while loop:
#include <iostream>
#include <fstream>
using namespace std;
int zapis()
{
fstream file;
string text;
file.open("data.txt", ios::app);
cout << "Type in text that you would like to store: ";
getline(cin, text);
file << text << endl;
file.close();
return 0;
}
int odczyt()
{
fstream file;
string line;
int nr_lini = 1;
file.open("data.txt", ios::in);
if(file.good()==false)
{
cout << "Error occured!";
}
else
{
while(getline(file, line))
{
getline(file, line);
cout << line;
}
}
file.close();
return 0;
}
int main()
{
zapis();
odczyt();
return 0;
}
Why call getline twice in your loop? Also pay attention to the semi-colons
while(getline(file, line));
^
What do you think the semi-colon there does?
This is correct
while (getline(file, line))
{
cout << line;
}
Your code is correct, just loop through the file. Also, you could make the function void, as it always returns 0, with you not doing anything with the return value.
void odczyt(){
fstream file;
string line;
file.open("data.txt", ios::in);
if(!file.good())
{
cout << "Error occured!";
}
else
{
while(getline(file, line);) { // while text file still has lines, you write the line and read next
cout << line;
}
}
file.close();
}
I have made a Quizlet code to save a word with its translation(in Russian) in csv file.
So, the 'add' and 'read' functions work perfectly but I have been trying to make the 'delete' function remove a line when I give a substring of that line.
update: I am trying to copy all the lines except the one that i wanna delete to a new file and then rename it.
but when the new file is created, it is empty!
ex: in the file, line 1: apple яблоко.
input: apple, and then the entire is being deleted.
here is my code: I just have a problem in void quizlet::DeleteWord()
#include <string>
#include <iostream>
#include <vector>
#include<fstream>
#include <sstream>
#include<cstdlib>
using namespace std;
class quizlet {
private:
std::string filename;
std::vector<std::string> lines;
public:
quizlet(std::string filename) : filename(filename) {}
void AddWord(std::string, std::string);
vector<string> ReadAllWords();
void DeleteWord();
};
void quizlet::AddWord(std::string word, std::string translation) {
cout << "Write a word and its translation separated by a space:" << std::endl;
cin >> word >> translation;
// file pointer
fstream fout;
// opens an existing csv file or creates a new file.
fout.open("words.txt",ios::out | ios::app);
// Insert the data to file
fout <<word<<" "<<translation<<endl;
std::cout << "Saved new card: " << word << "/" << translation << std::endl;
}
vector<string> quizlet::ReadAllWords() {
// File pointer
fstream fin;
// Open an existing file
fin.open("words.txt", ios::in);
// Read the Data from the file
// as String Vector
vector <string> rows;
string line, word, temp;
while (getline(fin, line)) {
cout << line << std::endl;
rows.push_back(line);
stringstream s(line);
}
return rows;
}
void quizlet::DeleteWord() {
string line;
fstream fin;
fstream fout;
fin.open("words.txt", ios::in);
fout.open("new.txt",ios::out | ios::app);
string token;
cin>>token;
vector <string> lines;
while (getline(fin, line)) {
if (line.find(token) != string::npos) {
cout << line << endl;
fin << line << endl;
cout<<"the line has been deleted!";
//remove (line);
}
}
fin.close();
fout.close();
remove("words.txt");
rename("new.txt", "words.txt");
cout << "\nChanges has Successfully been made...... Data Saved\n" << endl;
}
int main() {
auto Quizlet = quizlet("words.txt");
string word, translation;
while (true) {
std::string command;
std::cin >> command;
if (command == "add") {
Quizlet.AddWord(word, translation);
} else if (command == "read") {
Quizlet.ReadAllWords();
}
else if (command == "delete") {
Quizlet.DeleteWord();
}
else {
return 0;
}
}
}
Post-update edit:
My original answer now makes much more sense given what you are trying to do. You should read the whole file in at once, make any additions and deletions in-memory you want, then overwrite the original file with the whole, new, list.
Original answer:
Consider reading the file into memory via a std::map<std::string,std::wstring> instead of a std::vector<std::string> of lines in the file.
Using this approach, adding and deleting a word and its translation is simple.
Adding:
//if-guard only needed if you want to protect against overwriting already-existing words.
auto found_iter = cards.find(word);
if(found_iter == cards.end()) {
cards.insert_or_assign(word, translation);
}
Deleting:
auto found_iter = cards.find(word);
if(found_iter != cards.end()) {
cards.erase(found_iter);
}
Writing it back to the file is as simple as looping over the collection:
for(const auto& [word,translation] : cards) {
fout << word << ' ' << translation << '\n';
}
fout.close();
well, after trying for a long time.
I got this code and it works perfectly with no errors.
thank you all!
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstdlib>
using namespace std;
class quizlet {
private:
std::string filename;
std::vector<std::string> lines;
public:
quizlet(std::string filename) : filename(filename) {}
void AddWord(std::string, std::string);
vector<string> ReadAllWords();
void DeleteWord(std::string);
};
void quizlet::AddWord(std::string word, std::string translation) {
cout << "Write a word and its translation separated by a space:" << std::endl;
cin >> word >> translation;
// file pointer
fstream fout;
// opens an existing csv file or creates a new file.
fout.open("words.txt",ios::out | ios::app);
// Insert the data to file
fout << word << " " << translation << endl;
std::cout << "Saved new card: " << word << "/" << translation << std::endl;
}
vector<string> quizlet::ReadAllWords() {
// File pointer
fstream fin;
// Open an existing file
fin.open("words.txt", ios::in);
// Read the Data from the file
// as String Vector
vector <string> rows;
string line, word, temp;
while (getline(fin, line)) {
cout << line << std::endl;
rows.push_back(line);
stringstream s(line);
}
return rows;
}
void quizlet::DeleteWord(string token) {
string line;
fstream fin;
fstream fout;
fin.open("words.txt", ios::in);
fout.open("new.txt",ios::out | ios::app);
cin >> token;
vector<string> lines;
while(getline(fin, line)) {
if(line.find(token) == string::npos) {
fout << line << endl;
}
}
fout.close();
fin.close();
remove("words.txt");
rename("new.txt", "words.txt");
cout << "\nChanges has Successfully been made...... Data Saved\n" << endl;
}
int main() {
auto Quizlet = quizlet("words.txt");
string word, translation, token;
while(true) {
std::string command;
std::cin >> command;
if(command == "add") {
Quizlet.AddWord(word, translation);
} else if(command == "read") {
Quizlet.ReadAllWords();
} else if(command == "delete") {
Quizlet.DeleteWord(token);
} else {
return 0;
}
}
}
i was wondering how to use c++ ifstream/ofstream to copy a file and save it as another name.
this is as far as i got. I know how to get the file, its just that i don't know how to copy that file and save it as a different name.
#include<iostream>
#include<fstream>
#include<string>
namespace std;
int main()
{
ofstream
ifstream
cout << "enter your file you want to copy"<< endl;
cin >> input_file_name;
in_file.open(input_file_name);
if (!in_file)
{
cout <<" there is no such file"<<endl;
return 0;
}
cout <<" enter the name you want to save this copy file"<<endl;
cin >> output_file_name;
out_file.open(output_file_name);
if (!out.file)
{
cout<<"file is not available"<<endl;
return 0;
}
in_file.close();
out_file.close();
return 0;
}
rdbuf with overloaded << is standard way to go.
ifstream src;
ofstream dst;
src.open("from", ios::in | ios::binary);
dst.open("toto", ios::out | ios::binary);
dst << src.rdbuf();
src.close();
dst.close();
Copy a file and save it on another file:
#include <fstream>
#include <iostream>
#include <string>
int main(int arc, char* argv[]) {
std::ifstream file1(argv[1]);
std::ofstream file2(argv[2]);
std::string line;
if (file1.good() && file2.good()) {
while (getline(file1, line)) {
file2 << line;
file2 << '\n';
}
}
file1.close();
file2.close();
}
Basically you want to read a character at a time and write said character to the output stream. There's a get() overload which accepts a streambuf output variable that would work. You could also use the example on cplusplus.com rdbuf documentation.
http://www.cplusplus.com/reference/fstream/ofstream/rdbuf/
This code below should give you a sense of what you want to do.
There are few things you should keep in mind, for example:
is the path of the file giving to read is valid?
or do you want to save the data from an output file if that file exists, before pushing new data?.
You could test this code by just creating a file into your desktop or any location, just change the filePath and destinationPath variables then run the code. (c++ 11)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
vector<string> readFromFile(const char *filePath) {
vector<string> container;
ifstream obj(filePath); // automatically our file would be open
if (obj.is_open()) { // we check anyways
string line = "";
while(getline(obj, line)) {
if (!line.empty()) // prevent us to insert empty line into our vector
container.push_back(line);
}
obj.close(); // close after we finish reading to avoid corruption
}
return container;
}
bool pipingToDestination(vector<string>data, const char *filePath) {
std::filebuf fb; fb.open(filePath,std::ios::out); // open the file
ostream obj(&fb);
if (!data.empty() && fb.is_open()) { // make sure we have some data && the file file is open to write
for (string x: data) { // c++11
obj << x << endl;
}
fb.close();
return true;
}
return false;
}
int main() {
string filePath = "/Users/lamar/Desktop/testFile.txt";
vector<string> data = readFromFile(filePath.c_str());
cout << "File has passed data into container ... \n";
for(string x: data) {
cout << x << endl;
}
cout << "Creating destination file \n";
string destinationPath = "/Users/lamar/Desktop/destFile.txt";
cout << "has piped data into file " << boolalpha << pipingToDestination(data, destinationPath.c_str());
return 0;
}
This is not the only way to do this, but this code should put you on a direction
Please help I'm new to C++
Using stacks Implementation
I should read a sample text file containing:
text file
begining to end
return text
And return a text file reading:
return text
begining to end
test file
This is the sample code to test the implementation:
#include <iostream>
#include <fstream>
#include <string>
#include "stack1.h"
using namespace std
void reverse (ifstream & infile, ofstream & outfile); //function prototype
int main () {
ifstream infile; // declaring a file for input
ofstream outfile; // declaring a file for output
infile.open ("c:\\myInputFile.txt");
if (!infile) { cout << "File could not be opened. Program terminated." << endl;
return 1; // terminates program
}
outfile.open ("c:\\myOutfile.txt");
reverse (infile, outfile);
infile.close();
outfile.close();
return 0;
}
void reverse (ifstream & infile, ofstream & outfile) {
string s;
stack<string> mystack;
getline(infile, s); // try to read a line of text from the file
while (!infile) { // while not end of file
mystack.push(s);
getline(infile, s); // try to read another line
}
while (! mystack.isEmpty() ) {
s = mystack.pop();
outfile << s << endl; // write s to the outfile
}
}
How about:
//open infile in and outfile out.
std::stack<std::string> lines;
std::string temp;
while(std::getline(in, temp)) lines.push(temp);
while(!lines.empty()) outfile << lines.pop() << std::endl;
I'm unsure exactly what your question is here though.
Edit: changed push_back() and pop_back to push() and pop() respectively (because those are what std::stack provides).
Get rid of the !
while (infile) { // while not end of file
You could use std::stack instead of whatever is in "stack1.h".
Check this you can directly store it without using stack.I think it should work.
int checkstatus(ifstream &in)
{
ios::iostate i;
i = in.rdstate();
if(i & ios::eofbit)
return 0;//cout << "EOF encountered\n";
else if(i & ios::failbit)
return 0;//cout<<"Non-Fatal I/O error\n";
else if(i & ios::badbit)
return 0;//cout<<"Fatal I/O error\n";
return 1;
}
int main()
{
ifstream in;
in.open("test.txt");
char c;
in.seekg(0,ios::end);
while(checkstatus(in) != 0)
{
in.seekg(-1,ios::cur);
in.get(c);
in.seekg(-1,ios::cur);
if(checkstatus(in) == 0)
break;
cout<<c;
}
return 0;
}