I am developing a program in c++ with lots of file io operation. I have defined a static ofstream in a common header so that it is accessible everywhere in the project. The structure of the codes are list as following: all common variable are defined in com.h, test.h and test.cpp are for a class called OPClass, main.cpp carry the main program
COM.H:
#ifndef __CLCOM__
#define __CLCOM__
#include <sstream>
#include <fstream>
#include <iostream>
using namespace std;
static ofstream out;
static stringstream ss;
#endif
TEST.H:
#ifndef __CL__
#define __CL__
#include <iostream>
#include <fstream>
#include "com.h"
using namespace std;
class OPClass
{
public:
void run(void);
void show(ostream &o) const;
};
#endif
TEST.CPP:
#include "com.h"
#include "test.h"
void OPClass::run(void)
{
out << "Here is run()" << endl;
show(out);
}
void OPClass::show(ostream &o) const
{
o << "hello!" << endl;
}
MAIN.CPP:
#include "com.h"
#include "test.h"
void runmain(void)
{
OPClass op;
out.open("output.txt", ios::out | ios::trunc);
out << endl << "State changed!" << endl;
op.run();
if (out.is_open()) out.close();
}
int main(int argc, char* argv[])
{
runmain();
return 0;
}
As you can see, the static ofstream was named as out and will be called in the main program and in the class. I am using mingw32 and didn't see any problem on compilation or upon running. But seems that only the information in runmain() will be written to the output file. Any other message written to that file in the class never appear in the output file. Why's that and how can I written a common file stream so everywhere in the project can access that? Thanks.
Each compilation unit is getting its own ss and out. Hence there is a different instance of them seen by main.cpp than by test.cpp.
You don't really need static here. To address this, rather than declaring the variables and their allocations in the header file you need to merely prototype them using the extern keyword.
#ifndef __CLCOM__
#define __CLCOM__
#include <sstream>
#include <fstream>
#include <iostream>
// Note: don't put "using" statements in headers
// use fully qualified names instead
extern std::ofstream out;
extern std::stringstream ss;
#endif
Where you actually put your declarations is up to you, just make sure it's only in one place. That could be a com.cpp file or you could stick it in main.cpp if that's appropriate for your project.
std::ofstream out;
std::stringstream ss;
Not that global variables like this are a good idea, anyway...
Preemptive statement: You should accept #HostileFork's answer.
Just as an addendum, an easy way to show what's happening is to print out the address of out whenever you try to use it.
If you add these couple statements:
void OPClass::run(void)
{
cout << "Address of 'out' = " << &out << endl;
out << "Here is run()" << endl;
show(out);
}
And:
void runmain(void)
{
cout << "Address of 'out' = " << &out << endl;
OPClass op;
out.open("output.txt", ios::out | ios::trunc);
out << endl << "State changed!" << endl;
op.run();
if (out.is_open()) out.close();
}
You'll notice that the two print statements for out display two different addresses. This should tell you that you're actually getting two instances of out created as two distinct variables. The methods in your OPClass are trying to write to a completely different output stream. It has to do with the way you're using static in a global context; it doesn't behave like you think it does. In a global context, declaring something static binds it to the local scope of the file it's in.
Related
I'm having a problem when using the class files and the compiler error says "error: 'x' was not declared on this code" while it points out the cout, string, and endl. I have already wrote "#include " and "#include " in both header, class, and main file.
(Sorry for my English)
I'm just a beginner and I wanted to know the basics
Added #include and #include in both files
//Main File (main.cpp)
#include <iostream>
#include "test.h"
#include <string>
using namespace std;
int main()
{
test *person = new person("Phroton",14)
person.Display();
return 0;
}
//test.h
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <string>
class test
{
private:
string name;
int age;
public:
void Display(){
cout << "I'm " << name << " and I'm " << age << "years old" << endl;
}
};
#endif // TEST_H
//test.cpp (There is no problem with this file at all)
#include "test.h"
#include <iostream>
#include <string>
test::test(string iname, int iage)
{
name = new string;
age = new int;
*name = iname;
*age = iage;
}
test::~test()
{
delete name;
delete age;
cout << "Info Deleted" << endl;
}
Answering the specific problem you have asked:
This is because you have not specified the namespace cout and endl belong to in the file test.h.
The statement in Display should be:
std::cout << "I'm " << name << " and I'm " << age << "years old" << std::endl;
The alternative to this is the using namespace std declaration but this is considered a bad practice (especially in a header file).
Note:
You do not need using namespace std in main.cpp as you are not using any functions from the std namespace there. Even if you do, use the std::name instead of the using declaration.
Member function definitions are usually present in .cpp files. So you can define the function Display to test.cpp.
Also consider moving away from raw pointers to smart pointers.
I think there are many solutions outside for my problem but I dont get it, I'm kind of new to structs - so please help me..
OK my problem is I declare a struct in my header.h file and there is a function also inside that puts a string in one of the struct values and in the header file I can also output the string, but I want that struct and that !!value!! in a different cpp file where I can access to that value - so here is my code
header.h
#include <iostream>
#include <string.h>
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
struct FUNCTIONS
{
std::string f_name;
};
//extern FUNCTIONS globalStruct;
//put in struct variable
void put2struct()
{
struct FUNCTIONS struct1;
struct1.f_name = "FUNCTION";
std::cout << "Functionname: " << struct1.f_name << std::endl;
}
#endif //FUNCTIONS_H
and main.cpp
#include <iostream>
#include <string.h>
#include "header.h"
using namespace std;
int main(int argc, char const *argv[])
{
struct FUNCTIONS globalStruct;
put2struct();
//FUNCTIONS struct1;
std::cout << "Functionname2: " << globalStruct.f_name << std::endl;
return 0;
}
I hope somebody can help me I really dont get it how to do this :/
There is no way to directly access a local variable outside the block where it is defined. Because struct1 is an automatic variable, it is destroyed when put2struct returns, and no longer exists after that.
You can write a function that takes a FUNCTIONS by reference, and modify put2struct to call that function. That way you can access struct1 from a different cpp file:
void foo(FUNCTIONS&);
void put2struct()
{
FUNCTIONS struct1;
// do your thing
foo(struct1);
}
// another file
void foo(FUNCTIONS& object) {
// you have access to the object passed by reference
}
I am trying to learn C++, however, the parameter to a method I have in my own class is misbehaving. When it uses a dataType of 'int', it works fine with no errors, but when I attempt to change it to a 'string' dataType, the program crashes with this error.
Error 1 error C2061: syntax error : identifier 'string' in temp.h ln
8 col 1
The classes I am using are as follows:
WORKING CODE
TesterClass.cpp // Entry Point
#include "stdafx.h"
#include "Temp.h"
int _tmain(int argc, _TCHAR* argv[])
{
Temp tmp;
tmp.doSomething(7);
return 0;
}
Temp.h
#pragma once
class Temp
{
public:
Temp();
void doSomething(int blah);
};
Temp.cpp
#include "stdafx.h"
#include "Temp.h"
#include <iostream>
#include <string>
using std::string;
Temp::Temp()
{
std::cout << "Entry" << std::endl;
string hi;
std::cin >> hi;
std::cout << hi << std::endl;
}
void Temp::doSomething(int blah)
{
std::cout << blah;
}
BROKEN CODE
Temp.h
#pragma once
class Temp
{
public:
Temp();
void doSomething(string blah);
};
Temp.cpp
#include "stdafx.h"
#include "Temp.h"
#include <iostream>
#include <string>
using std::string;
Temp::Temp()
{
std::cout << "Entry" << std::endl;
string hi;
std::cin >> hi;
std::cout << hi << std::endl;
}
void Temp::doSomething(string blah)
{
std::cout << blah;
}
When I adjust the parameter 'blah' to be a string, in both the .h and .cpp file, the problem occurs.
I have looked around, but none of the answers seem to solve my problem. I would greatly love help on this an I am out of ideas. I have tried reinstalling C++, messing with:
using namepace std;
using std::string;
std::string instead of string
etc.
If you know how to solve my problem I would love to hear from you. I am more than happy to provide more information.
C++ performs single-pass compilation, so std::string needs to be declared before you use it at all - including in the header file.
// Temp.h
#pragma once
#include <string>
class Temp
{
public:
Temp();
void doSomething(std::string blah);
};
I would encourage you to be specific in your header files when specifying classes like this, because you might easily come across another library that defines it's own string and then you would run into naming conflicts. Save the using import statements for your cpp files.
πάντα ῥεῖ had the write answer, thankyou!
They said to use std::string when needed, and to also #include <string> in the header file.
I am really new in C++, and I can not solve the compilation error below.
data_structure.h
#include <stdint.h>
#include <list>
namespace A {
class B {
public:
bool func_init(); // init
};
};
data_structure.cpp
#include "data_structure.h"
using namespace A;
bool B::func_init(){
std::cout << "test init" << std::endl;
return true;
}
main.cpp
#include <iostream>
#include "data_structure.h"
using namespace A;
int main( int argc, char **argv ) {
A::B s;
s.func_init();
return 0;
}
I have an error as the following
undefined reference to `A::B::func_init()'
Please kindly advice why I can not get the func_init, eventhough it is declared as public? I have put also the correct namespace there.
Would appreciate for any response.
That's a linker error, so you're probably not compiling all your source files, or linking them together, or making some weird use of the C compiler (I see your files have the extension .c, some compilers treat them as C-source).
g++ main.cpp data_structure.cpp -o test should do it.
However I did need to add #include <iostream> to your data_structure.cpp file to resolve
data_structure.cpp: In member function ‘bool A::B::func_init()’:
data_structure.cpp:7:5: error: ‘cout’ is not a member of ‘std’
data_structure.cpp:7:33: error: ‘endl’ is not a member of ‘std’
and make it compile.
The definition of a function has to be in the namespace that declares the function. A using declaration just pulls in names from the namespace; it doesn't put you inside it. So you have to write data_structure.cpp like this:
#include "data_structure.h"
#include <iostream>
namespace A {
bool B::func_init() {
std::cout << "test init" << std::endl;
return true;
}
}
Or, if you prefer, you can use the namespace name explicitly in the function definition:
bool A::B::func_init() {
std::cout << "test init" << std::endl;
return true;
}
Have you tried not putting
using namespace A;
in your data_structure.cpp file and instead putting:
#include "data_structure.h"
bool A::B::func_init() {
std::cout << "test init" << std::endl;
return true;
}
I have the feeling that when you use using namespace A; doesn't let you append function definitions to the namespace, but only tells the compiler/linker where to look for Types or Functions...
Another theory:
Have you tried nesting your CPP code in the same namespace?
#include "data_structure.h"
namespace A {
bool B::func_init() {
std::cout << "test init" << std::endl;
return true;
}
}
I have been stuck on this, my teacher doesn't even know what's going on. If someone could please help me that would be greatly appreciated.
I have declared item in the header file in the Line struct. However when calling on it in the Line::display() method, i get an error stating that the variable was not declared in the scope. I have showed my teacher and my peers and no one seems to know of the solutions.
Here is my .h:
//Line.h
#define MAX_CHARS 40
struct Line {
public:
bool set(int n, const char* str);
void display() const;
private:
char item[MAX_CHARS];
int no;
};
And here is my .cpp file.
// Line.cpp
#include "Line.h"
#include <iostream>
using namespace std;
#define MAX_CHARS 40
void Line::display() const {
cout << no << ' ' << item << endl;
}
Any help with this is awesome. Thanks in advance.
If this is your actual code, you're probably getting the header from somewhere else. Try:
#include "C:\\fullPathToHeader\\Line.h"
#include <iostream>
using namespace std;
void Line::display() const {
cout << no << ' ' << item << endl;
}
Also:
don't re-define MAX_CHARS in the cpp file.
use include guards for the header.
To make Line::display const implies you do not need instance variable data.
// Line.cpp
#include "Line.h"
#include <iostream>
using namespace std;
void Line::display()
{
cout << no << ' ' << Line::item << endl;
}