streams as function arguments, c++ - c++

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

Related

default constructor called instead of parameterized constructor

**the first constructor is supposed to take words from a txt file and the second one takes words from the string and add it to fileVec vector.
i'm trying to call a parameterized constructor but it doesn't work, instead it calls the default constructor
**
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
class stringSet
{
private:
int i = 0;
string fileName, line, word, word2;
istringstream iss;
fstream file;
vector<string> fileVec;
public:
string str = "that's a string for parameterized constructor";
stringSet()
{
cout << "Please enter filename: ";
getline(std::cin, fileName);
fileName += ".txt";
file.open(fileName, ios::in);
if (file.is_open())
{
while (getline(file, line))
{
iss.clear();
iss.str(line);
while (iss.good())
{
iss >> word;
fileVec.push_back(word);
cout << fileVec[i] << endl;
i++;
}
}
}
}
stringSet(string str)
{
istringstream iss2(str);
while (iss2 >> word2)
fileVec.push_back(word2);
cout << fileVec[i] << endl;
i++;
}
};
int main()
{
// stringSet();
stringSet(str);
return 0;
}
that code calls stringSet() instead of stringSet(str)
Issue similar to most vexing parse.
stringSet(str); // Variable declaration!
declares a variable str.
It is similar to
stringSet str;
You might use {..} syntax:
stringSet{str}; // Temporary created (assuming some std::string str available).

Getting more than one line from .txt file C++

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();
}

C++ copying another file

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

How to tell your program which file you want to read C++

#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.";
}
}

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());
}