Problem to print in file

Hi,

I am trying to develop the code below in goal to have the same output in the the console and file.

However, the expected output is only right on the consol;e but not in the file.

The console's output is:

Flot [main]:
Level:0 func_1
[tab] Level:1 func_2
[Tab][Tab] Level:2 func_3
Level:0 func_2
[tab] Level:1 func_3
Level:0 func_3


The file's output is :

Flot [main]:
[tab] Level: 2 func_3
[tab] Level: 1 func_2
[tab] Level: 1 func_3
[tab] Level: 0 func_1
[tab] Level: 0 func_2
[tab] Level: 0 func_3


The code is the below.

Thanks in advance for your help.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#ifndef _FLOWTRACER_H_
#define _FLOWTRACER_H_

#include <string>
#include <stack>
#include <vector>
#include <iostream>
#include <stdio.h>

using namespace std;

class debugFlowTracer
{
private:
	std::string m_sFlowName;
	std::vector< debugFlowTracer > m_activefunctionStack;
	bool						   m_bRemoved;

	FILE * pFile;

protected:
	virtual void AddFlow();
	virtual void RemoveFlow();

public:


	debugFlowTracer(void)
	{
		m_sFlowName = "Inconnu";
		m_bRemoved = false;
		AddFlow();
	}

	debugFlowTracer(const char *strFlow)
	{
		m_sFlowName = strFlow;
		m_bRemoved = false;
		AddFlow();
	}
	debugFlowTracer( const debugFlowTracer& aCopy )
	{
		m_sFlowName = aCopy.m_sFlowName;
		std::vector< debugFlowTracer >::const_iterator iter;
		for ( iter = aCopy.m_activefunctionStack.begin(); iter != aCopy.m_activefunctionStack.end(); ++iter )
			m_activefunctionStack.insert( m_activefunctionStack.end(), (*iter) );
	}


	~debugFlowTracer(void)
	{
		if ( !m_bRemoved )
			RemoveFlow();
		m_bRemoved = true;
	}

	std::string Name()
	{
		return m_sFlowName;
	}

	void AddSubFlow( debugFlowTracer& cSubFlow )
	{
		// Placement en haut de la pile de fonction active
		m_activefunctionStack.insert( m_activefunctionStack.end(), cSubFlow );
	}
	void PrintStack(int iLevel)
	{
		pFile = fopen ("myfile.txt","a");//PSA
		std::vector< debugFlowTracer >::iterator iter;
		for ( iter = m_activefunctionStack.begin(); iter != m_activefunctionStack.end(); ++iter )
		{
			for ( int i=0; i<iLevel; ++i )
				putchar ('\t'); //putchar writes character to the current position in the standard output (stdout) and advances the internal file position indicator to the next position.
			    fputc ( ('\t'), pFile );
			printf("Level:%d %s\n", iLevel,(*iter).Name().c_str());
			fprintf (pFile, "Level: %d %s\n",iLevel,(*iter).Name().c_str());
			(*iter).PrintStack(iLevel+1);

		}
		 fclose (pFile);

	}

};

#endif

class debugFlowTracerManager
{
private:
	std::stack< debugFlowTracer> m_functionStack;
	static debugFlowTracerManager *m_Instance;
	FILE * pFile;

public:
	static debugFlowTracerManager *Instance()
	{
		if ( m_Instance == NULL )
			m_Instance = new debugFlowTracerManager();
		return m_Instance;
	}
	void addFlow( debugFlowTracer& cFlow )
	{
		m_functionStack.push( cFlow );
	}

	void removeFlow(debugFlowTracer& cFlow)
	{
		if ( m_functionStack.empty() )
			return;

		// Accède à l'élément du haut
		debugFlowTracer t = m_functionStack.top();

		// Le supprime.
		m_functionStack.pop();

		// S'il reste quelque chose, on l'ajoute
		if ( m_functionStack.empty() )
		{
			pFile = fopen ("myfile.txt","a");//PSA
			printf("Flot [%s]:\n", t.Name().c_str() );
			fprintf (pFile,"Flot [%s]:\n", t.Name().c_str() );
			fclose (pFile);
			t.PrintStack(0);
		}
		else
			m_functionStack.top().AddSubFlow( t );

	}

private:
	debugFlowTracerManager()
	{
	}
	debugFlowTracerManager(const debugFlowTracerManager& aCopy )
	{
	}
	virtual ~debugFlowTracerManager(void)
	{
	}
};

debugFlowTracerManager *debugFlowTracerManager::m_Instance = NULL;

void debugFlowTracer::AddFlow()
{
	debugFlowTracerManager::Instance()->addFlow( *this );
}

void debugFlowTracer::RemoveFlow()
{
	debugFlowTracerManager::Instance()->removeFlow( *this );
}

void func_3()
{
   debugFlowTracer flow("func_3");
}

void func_2()
{
   debugFlowTracer flow("func_2");
   func_3();
}

void func_1()
{
   debugFlowTracer flow("func_1");
   func_2();
}

int main(int argc, char* argv[])
{
   debugFlowTracer mainFlow("main");
   func_1();

   func_2();
   func_3();
   
   //cout << "Ok!" << endl;

   return 0;

   //system ("BREAK");
   //return EXIT_SUCCESS;
}
I think you should put both putchar and fputc in inside the loop.
1
2
3
4
5
for ( int i=0; i<iLevel; ++i )
{
	putchar ('\t');
	fputc ( ('\t'), pFile );
}
Hello,

Thanks, you are wright, i have just done this but now I have this file's output :


Flot [main]:
[Tab][Tab]Level: 2 func_3
[Tab]Level: 1 func_2
[Tab]Level: 1 func_3
Level: 0 func_1
Level: 0 func_2
Level: 0 func_3


instead of (the console's output):

Flot [main]:
Level:0 func_1
[tab] Level:1 func_2
[Tab][Tab] Level:2 func_3
Level:0 func_2
[tab] Level:1 func_3
Level:0 func_3



The new code is the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#ifndef _FLOWTRACER_H_
#define _FLOWTRACER_H_

#include <string>
#include <stack>
#include <vector>
#include <iostream>
#include <stdio.h>

using namespace std;

class debugFlowTracer
{
private:
	std::string m_sFlowName;
	std::vector< debugFlowTracer > m_activefunctionStack;
	bool						   m_bRemoved;

	FILE * pFile;

protected:
	virtual void AddFlow();
	virtual void RemoveFlow();

public:


	debugFlowTracer(void)
	{
		m_sFlowName = "Inconnu";
		m_bRemoved = false;
		AddFlow();
	}

	debugFlowTracer(const char *strFlow)
	{
		m_sFlowName = strFlow;
		m_bRemoved = false;
		AddFlow();
	}
	debugFlowTracer( const debugFlowTracer& aCopy )
	{
		m_sFlowName = aCopy.m_sFlowName;
		std::vector< debugFlowTracer >::const_iterator iter;
		for ( iter = aCopy.m_activefunctionStack.begin(); iter != aCopy.m_activefunctionStack.end(); ++iter )
			m_activefunctionStack.insert( m_activefunctionStack.end(), (*iter) );
	}


	~debugFlowTracer(void)
	{
		if ( !m_bRemoved )
			RemoveFlow();
		m_bRemoved = true;
	}

	std::string Name()
	{
		return m_sFlowName;
	}

	void AddSubFlow( debugFlowTracer& cSubFlow )
	{
		// Placement en haut de la pile de fonction active
		m_activefunctionStack.insert( m_activefunctionStack.end(), cSubFlow );
	}
	void PrintStack(int iLevel)
	{
		pFile = fopen ("myfile.txt","a");//PSA
		std::vector< debugFlowTracer >::iterator iter;
		for ( iter = m_activefunctionStack.begin(); iter != m_activefunctionStack.end(); ++iter )
		{
			for ( int i=0; i<iLevel; ++i )
			{putchar ('\t'); //putchar writes character to the current position in the standard output (stdout) and advances the internal file position indicator to the next position.
			fputc ( ('\t'), pFile );
			}
			printf("Level:%d %s\n", iLevel,(*iter).Name().c_str());
			fprintf (pFile, "Level: %d %s\n",iLevel,(*iter).Name().c_str());
			(*iter).PrintStack(iLevel+1);

		}
		 fclose (pFile);

	}

};

#endif

class debugFlowTracerManager
{
private:
	std::stack< debugFlowTracer> m_functionStack;
	static debugFlowTracerManager *m_Instance;
	FILE * pFile;

public:
	static debugFlowTracerManager *Instance()
	{
		if ( m_Instance == NULL )
			m_Instance = new debugFlowTracerManager();
		return m_Instance;
	}
	void addFlow( debugFlowTracer& cFlow )
	{
		m_functionStack.push( cFlow );
	}

	void removeFlow(debugFlowTracer& cFlow)
	{
		if ( m_functionStack.empty() )
			return;

		// Accède à l'élément du haut
		debugFlowTracer t = m_functionStack.top();

		// Le supprime.
		m_functionStack.pop();

		// S'il reste quelque chose, on l'ajoute
		if ( m_functionStack.empty() )
		{
			pFile = fopen ("myfile.txt","a");//PSA
			printf("Flot [%s]:\n", t.Name().c_str() );
			fprintf (pFile,"Flot [%s]:\n", t.Name().c_str() );
			fclose (pFile);
			t.PrintStack(0);
		}
		else
			m_functionStack.top().AddSubFlow( t );

	}

private:
	debugFlowTracerManager()
	{
	}
	debugFlowTracerManager(const debugFlowTracerManager& aCopy )
	{
	}
	virtual ~debugFlowTracerManager(void)
	{
	}
};

debugFlowTracerManager *debugFlowTracerManager::m_Instance = NULL;

void debugFlowTracer::AddFlow()
{
	debugFlowTracerManager::Instance()->addFlow( *this );
}

void debugFlowTracer::RemoveFlow()
{
	debugFlowTracerManager::Instance()->removeFlow( *this );
}

void func_3()
{
   debugFlowTracer flow("func_3");
}

void func_2()
{
   debugFlowTracer flow("func_2");
   func_3();
}

void func_1()
{
   debugFlowTracer flow("func_1");
   func_2();
}

int main(int argc, char* argv[])
{
   debugFlowTracer mainFlow("main");
   func_1();

   func_2();
   func_3();
   
   //cout << "Ok!" << endl;

   return 0;

   //system ("BREAK");
   //return EXIT_SUCCESS;
}

You are opening the same file many times while writing to it. I don't know if that could cause problems. Try open the file just once and use the same FILE* to do all the output.
This is what i am trying to do using a static file but encounter several errors...
I have got it: I had obviously to declare the file global (ie: outside the two class).

Thanks a lot for your help Peter.

Hello,

I have a new issue when i separate the definition and the bodies of the classes in respectively .cpp and .h files.

I have the following error message :

1>------ Build started: Project: TraceFlowManager2, Configuration: Debug Win32 ------
1>Compiling...
1>FlowTracer.cpp
1>c:\designcpp\include\flowtracer.h(75) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : see declaration of 'fopen'
1>c:\designcpp\include\flowtracermanager.h(39) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : see declaration of 'fopen'
1>Generating Code...
1>Skipping... (no relevant changes detected)
1>FlowTracerMain.cpp
1>FlowTracerManager.cpp
1>Linking...
1>FlowTracerManager.obj : error LNK2005: "struct _iobuf * pFile" (?pFile@@3PAU_iobuf@@A) already defined in FlowTracerMain.obj
1>FlowTracer.obj : error LNK2005: "struct _iobuf * pFile" (?pFile@@3PAU_iobuf@@A) already defined in FlowTracerMain.obj
1>C:\MoonDragon\DistanceLearning\cpp\code\TraceFlowManager2\Debug\TraceFlowManager2.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Build log was saved at "file://c:\MoonDragon\DistanceLearning\cpp\code\TraceFlowManager2\Debug\BuildLog.htm"
1>TraceFlowManager2 - 3 error(s), 2 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Last edited on
The files are below.

=====================
Flowtracer.h
=====================
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifndef _FLOWTRACER_H_
#define _FLOWTRACER_H_

#include <string>
#include <stack>
#include <vector>
#include <stdio.h>

FILE * pFile;

class debugFlowTracer
{
private:
	std::string m_sFlowName;
	std::vector< debugFlowTracer > m_activefunctionStack;
	bool						   m_bRemoved;
protected:
	virtual void AddFlow();
	virtual void RemoveFlow();

public:
	debugFlowTracer(void)
	{
		m_sFlowName = "Unknown";
		m_bRemoved = false;
		AddFlow();
	}

	debugFlowTracer(const char *strFlow)
	{
		m_sFlowName = strFlow;
		m_bRemoved = false;
		AddFlow();
	}

	debugFlowTracer( const debugFlowTracer& aCopy )
	{
		m_sFlowName = aCopy.m_sFlowName;
		std::vector< debugFlowTracer >::const_iterator iter;
		for ( iter = aCopy.m_activefunctionStack.begin(); iter != aCopy.m_activefunctionStack.end(); ++iter )
			m_activefunctionStack.insert( m_activefunctionStack.end(), (*iter) );
	}

	~debugFlowTracer(void)
	{
		if ( !m_bRemoved )
			RemoveFlow();
		m_bRemoved = true;
	}

	std::string Name()
	{
		return m_sFlowName;
	}

	void AddSubFlow( debugFlowTracer& cSubFlow )
	{
		// Just push it on top of the active function stack
		m_activefunctionStack.insert( m_activefunctionStack.end(), cSubFlow );
	}
	//void PrintStack(int iLevel)
	//{
	//	std::vector< debugFlowTracer >::iterator iter;
	//	for ( iter = m_activefunctionStack.begin(); iter != m_activefunctionStack.end(); ++iter )
	//	{
	//		for ( int i=0; i<iLevel; ++i )
	//			putchar ('\t');
	//		printf("Level:%d %s\n",iLevel, (*iter).Name().c_str() );
	//		(*iter).PrintStack(iLevel+1);
	//	}
	//}

	void PrintStack(int iLevel)
	{
		pFile = fopen ("myfile.txt","a");//PSA
		std::vector< debugFlowTracer >::iterator iter;
		for ( iter = m_activefunctionStack.begin(); iter != m_activefunctionStack.end(); ++iter )
		{
			for ( int i=0; i<iLevel; ++i )
			{putchar ('\t'); //putchar writes character to the current position in the standard output (stdout) and advances the internal file position indicator to the next position.
			fputc ( ('\t'), pFile );
			}
			printf("Level:%d %s\n", iLevel,(*iter).Name().c_str());
			fprintf (pFile, "Level: %d %s\n",iLevel,(*iter).Name().c_str());
			(*iter).PrintStack(iLevel+1);

		}
		 //fclose (pFile);
	}

};

#endif 


==============================
FlowTracerManager.h
==============================
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#ifndef FLOWTRACERMANAGER_H
#define FLOWTRACERMANAGER_H

#include "FlowTracer.h"

class debugFlowTracerManager
{
private:
	std::stack< debugFlowTracer> m_functionStack;
	static debugFlowTracerManager *m_Instance;

public:
	static debugFlowTracerManager *Instance()
	{
		if ( m_Instance == NULL )
			m_Instance = new debugFlowTracerManager();
		return m_Instance;
	}

	void addFlow( debugFlowTracer& cFlow )
	{
		m_functionStack.push( cFlow );
	}

	void removeFlow(debugFlowTracer& cFlow)
	{
		if ( m_functionStack.empty() )
			return;

		// Get the top element
		debugFlowTracer t = m_functionStack.top();

		// Remove it.
		m_functionStack.pop();

		// If there is anything left, add it
		if ( m_functionStack.empty() )
		{
			pFile = fopen ("myfile.txt","a");//PSA
			printf("Flot [%s]:\n", t.Name().c_str() );
			fprintf (pFile,"Flot [%s]:\n", t.Name().c_str() );
			//fclose (pFile);
			t.PrintStack(0);
		}
		else
			m_functionStack.top().AddSubFlow( t );
	}

private:
	debugFlowTracerManager()
	{
	}

	debugFlowTracerManager(const debugFlowTracerManager& aCopy )
	{
	}
	
	virtual ~debugFlowTracerManager(void)
	{
	}
};
#endif

=============================
FlowTracerManager.cpp
=============================
1
2
3
#include "FlowTracerManager.h"

debugFlowTracerManager *debugFlowTracerManager::m_Instance = NULL;


=============================
FlowTracer.h
=============================
1
2
3
4
5
6
7
8
9
10
11
12
#include "FlowTracer.h"
#include "FlowTracerManager.h"

void debugFlowTracer::AddFlow()
{
	debugFlowTracerManager::Instance()->addFlow( *this );
}

void debugFlowTracer::RemoveFlow()
{
	debugFlowTracerManager::Instance()->removeFlow( *this );
}



=============================
FlowTracerMain.cpp
=============================

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#include <iostream>
#include "FlowTracerManager.h"
using namespace std;


void func_3()
{
   debugFlowTracer flow("func_3");
}

void func_2()
{
   debugFlowTracer flow("func_2");
   func_3();
}

void func_1()
{
   debugFlowTracer flow("func_1");
   func_2();
}

int main(int argc, char* argv[])
{
   debugFlowTracer mainFlow("main");
   func_1();

   func_2();
   func_3();
   
   //cout << "Ok!" << endl;

   return 0;

   //system ("BREAK");
   //return EXIT_SUCCESS;
}
Last edited on
Topic archived. No new replies allowed.