This is the header file File.h:
#include "common.h"
#ifndef FILE_H
#define FILE_H
using namespace std;
class File : public fstream{
public:
string file;
File(){
File("/tmp/text");
}
File(string file_name): file(file_name), fstream(file_name.c_str(), fstream::in | fstream::out){
}
void read_line();
};
#endif
And this is the File.cpp file:
#include "File.h"
void File::read_line(){
string line;
while(getline(*this, line)){
cout << "line: " << line << endl;
}
}
And following is the content of common.h
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string.h>
#include <string>
#include <stdio.h>
#include <stack>
#include <unistd.h>
#include <cassert>
#include <stdexcept>
#include <getopt.h>
#include <fstream>
#include <istream>
When compiling above code, I get below error:
/home/rohit/cpp/cmake_projs/tree/src/File.cpp: In member function ‘void File::read_line()’:
/home/rohit/cpp/cmake_projs/tree/src/File.cpp:7:24: error: no matching function for call to ‘File::getline(File&, std::__cxx11::string&)’
while(getline(*f, line)){
^
In file included from /usr/include/c++/7/iostream:40:0,
from /home/rohit/cpp/cmake_projs/tree/include/common.h:1,
from /home/rohit/cpp/cmake_projs/tree/include/File.h:1,
from /home/rohit/cpp/cmake_projs/tree/src/File.cpp:1:
But the code compiles fine when I put almost same code in a different function not related to File class:
void test(){
string line;
File *f = new File("/tmp/abc");
while(getline(*f, line)){
cout << "line: " << line << endl;
}
}
Why is this standard function hidden in the class function read_line() and not in an independent function?
It is a case of name lookup not working the way you expected.
Your class File inherits from fstream which inherits from istream. And istream has a member function getline, or two actually.
When you call an unqualified getline inside the class member, the compiler finds the inherited getline member and then doesn't look any further. In the free function test() there is no member function, so the compiler instead looks for the functions brought in by using namespace std;.
A solution is to explicitly use std::getline(*this, line) to show that you want to call a free function and not a member function.
This might also be yet another reason for not doing using namespace std;, but instead use std:: to refer to standard library names.
It is because fstream has a member getline that does not match, change the call to std::getline and it will work.
Related
I am new to c++ so forgive me if this question doesn't make much sense, but I have the follow files:
// main.cpp
#include <iostream>
#include <fstream>
using namespace std;
#include "second.h"
int main () {
string filename;
cin >> filename;
ifstream fileIn;
if( !openFile(fileIn, filename) ) {
cerr << "Could not open file \"" << filename << "\"" << endl;
cerr << "Shutting down" << endl;
return -1;
}
return 0;
}
// second.h
#include <string>
#include <fstream>
bool openFile(ifstream& inFile, string filename);
// second.cpp
#include "second.h"
#include <iostream>
#include <fstream>
using namespace std;
bool openFile(ifstream& inFile, string filename) {
inFile.open(filename);
if (inFile.fail()) {
return false;
}
return true;
}
My question is, why does c++ need so much redundancy?
Why do I need to #include <iostream> and <fstream> for both main.cpp and second.cpp if main already calls them? Why does the header files also need to include the function parameters (ifstream& inFile, string filename)? This just seems like a waste, when the function in second.cpp already asks for it. Why not just say openFile(); in the header and have function in second.cpp as for the parameters? This may just be more of a rant, but I just want a deeper understanding as to why theses redundancies are needed. Or is there something I am missing?
The general issue
The reason you have to include relevant headers in each .cpp file is because such .cpp files are compiled separately and independently; in more formal parlance: They constitute different "translation units". See also:
What is a "translation unit" in C++
Sometimes, when multiple translation units must all include several headers, we define a common single header file which containing all these inclusions - so that the .cpp files only need to include the common header to get all their necessary inclusions. Remember that inclusion is basically pasting the contents of the included file instead of the #include directive, and parsing that file as well, so an include-in-an-include is the same as making a direct #include.
Your specific example
In your specific example,
You actually don't need to #include <iostream> in second.cpp, because you only seem to be using constructs from <fstream>.
You don't need to #include <fstream> in any of the .cpp files, because they #include "second.h", which in turn includes <fstream> (so that it gets included when they are compiled, as well).
You can include #include <iostream> and <fstream> into second.h and then include it to main.cpp. Don't forget to use Include Guard, when you link to header files.
main.cpp uses std::ifstream, std::cin, and std::cerr, this is why your example requires the includes in main.cpp.
You should
read about #include directive to understand this idea and what's going on during compilation.
I am practicing using multiple files for C++ in Code::Blocks. I have three files, two source files named main.cpp and Cat.cpp, and a header file named Cat.h. Though I declare a function designed to output text in Cat.h, the implementation in the main function returns the error "'speak' was not declared in this scope."
I tried researching the error, but that was tricky because it's such a general error that can occur for a wide variety of reasons. I tried carefully checking for syntax errors or improper #include statements in my code, but I can't find anything.
This is in my main.cpp file:
#include <iostream>
#include "Cat.cpp"
#include "Cat.h"
using namespace std;
int main()
{
speak();
return 0;
}
this is my Cat.h file:
#ifndef CAT_H_INCLUDED
#define CAT_H_INCLUDED
void speak();
#endif
and this is my Cat.cpp file:
#include <iostream>
#include "Cat.h"
using namespace std;
void speak(){
cout << "Meow!!" << endl;
}
I am expecting speak() to run, but the error says it is not declared in this scope.
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ofstream myfile;
myfile.open ("test.txt");
return 0;
}
fstream is derived from iostream, why should we include both in the code above?
I removed fstream, however, there is an error with ofstream. My question is ofstream is derived from ostream, why fstream is needed to make it compile?
You need to include fstream because that's where the definition of the ofstream class is.
You've kind of got this backwards: since ofstream derives from ostream, the fstream header includes the iostream header, so you could leave out iostream and it would still compile. But you can't leave out fstream because then you don't have a definition for ofstream.
Think about it this way. If I put this in a.h:
class A {
public:
A();
foo();
};
And then I make a class that derives from A in b.h:
#include <a.h>
class B : public A {
public:
B();
bar();
};
And then I want to write this program:
int main()
{
B b;
b.bar();
return 0;
}
Which file would I have to include? b.h obviously. How could I include only a.h and expect to have a definition for B?
Remember that in C and C++, include is literal. It literally pastes the contents of the included file where the include statement was. It's not like a higher-level statement of "give me everything in this family of classes".
std::ofstream is defined in the <fstream> standard library header.
You need to include that header for its definition so that you can instantiate it.
The typedef ofstream and its associated class template are defined by #include <fstream> , so you need that header.
For your actual program, #include <iostream> is not needed. But you may wish to use your fstream object with some functions which operate on ostream or istreams .
Those functions are not defined by #include <fstream> and you need to include the right header for any functions you do use. Some implementations might cause #include <fstream> to also include <iostream> but this is not guaranteed by the C++ Standard.
For example, this code:
ofstream myfile;
myfile.open ("test.txt");
myfile << 1;
requires #include <ostream> (or , since C++11, #include <iostream> which is guaranteed to bring in #include <ostream>).
Goal: Using the class variable so that an ifstream declared in an object's member can be used by the following member of the same object, without having to use function header parameter passing.
Problem: The local ifstream of the created object test isn't being re-used in the second member of that object. I must be setting it up wrong, how do I fix this?
Classes and files feel like climbing a mountain to me right now, but I can't even find the first foothold - getting the blasted variable to work! I looked around the net for too long but all examples are convoluted, I just want to have something basic working to start tinkering with. I'm dead sure it's something stupidly easy that I'm missing, really frustrating >:[
main.cpp
#include "file.h
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
file test;
test.file_pass();
return 0;
}
file.h
#ifndef FILE_H
#define FILE_H
#include <fstream>
#include <iostream>
using namespace std;
class file
{
public:
file();
void file_pass();
//private:
ifstream stream;
};
#endif
file.cpp
#include "file.h"
//**********************************
//This will read the file.
file::file()
{
ifstream stream("Word Test.txt");
}
//**********************************
//This will output the file.
void file::file_pass()
{
//ifstream stream("Word Test.txt"); //if line activated, program works fine of course.
string line;
while(getline(stream, line))
cout << line << endl;
}
Here you are creating a new local variable with the same name as the class member:
file::file()
{
ifstream stream("Word Test.txt");
}
Instead you can use this to initialize the class member in the constructor:
file::file() : stream("Word Test.txt")
{
}
In the sample code below
std::string result = exec( "dir" ) ;
cout<<result;
I get the following error
error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::basic_string
I suspect there is a special method to print out an std::string.
Please help me debug this.
Also, I have included iostream.h, fstream.h and stream header files.
I suspect that you need to qualify cout with std::
std::cout << result;
or add using namespace::std to the top of your cpp file.
You need to include <string>
cout is defined in <iostream>. Getting the << syntax to work with std::strings requires <sstream>.
#include <iostream>
#include <sstream>
std::string result = "something";
std::cout << result << " and something else";
Answering my own question on behalf of #MrLister since he was inactive.
I should have included <iostream> and <fstream> without .h. Also using namespace std; should have been typed after that.
Ex:
#include <string>
#include <iostream>
#include <fstream>
#include <stdlib>
using namespace std;
Many many thanks to #MrLister.
And thanks to #dasblinkenlight. His answer enhanced a little bit.