Click here to Skip to main content
15,891,431 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Wasn't sure if to start a new thread or...in any case. I have a log file rgar is worinh ok up to the point that it won't print the results of a function that is in a header file. I tried to refernce ?ofstream myfile;" at the top of my header file but it says that I am redrfining "myfile". If I remove the reference then I get "myfile undeclared identifier. What to do? Previous post for refernece.
Function Not Printing To Log File[^]

C++
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
#include <windows.h>

using namespace std;

typedef vector<win32_find_data> tFoundFilesVector; 
std::string LastWriteTime;   
//int getFileList(wstring filespec, tFoundFilesVector &foundFiles) //uni
int getFileList(const char * filespec, tFoundFilesVector &foundFiles) //ansi
{ 
    WIN32_FIND_DATA findData; 
    HANDLE h; 
    int validResult=true; 
 
    int numFoundFiles = 0; 
    //h = FindFirstFile(filespec.c_str(), &findData); //uni 
	h = FindFirstFile((LPCSTR)filespec, &findData); //ansi 
    if (h == INVALID_HANDLE_VALUE) 
        return 0; 
 
    while (validResult) 
    { 
        numFoundFiles++; 
        foundFiles.push_back(findData); 
        validResult = FindNextFile(h, &findData); 
    } 
    FindClose(h);
	return numFoundFiles; 
} 
 
void showFileAge(tFoundFilesVector &fileList) 
{
	unsigned _int64 fileTime, curTime, age; 
    tFoundFilesVector::iterator iter; 
    FILETIME ftNow; 
    CoFileTimeNow(&ftNow); 
          curTime = ((_int64) ftNow.dwHighDateTime << 32) + ftNow.dwLowDateTime; 
 
          for (iter=fileList.begin(); iter<filelist.end();>
    { 
        fileTime = ((_int64)iter->ftLastWriteTime.dwHighDateTime << 32) + iter->ftLastWriteTime.dwLowDateTime; 
 
        age = curTime - fileTime;
		if (age <= (_int64)100000000UL) //10 seconds
		{
			rename(string("c:\\Users\\DS\\Downloads\\").append(string(iter->cFileName)).c_str(),(string("c:\\FAIL\\").append(string(iter->cFileName)).c_str()));
			wcout << " Delete: '" <<endl;
			extern ofstream; myfile << "\n   Delete  :";
			wcout << "FILE: '" << iter->cFileName << "', AGE: " << (_int64)age/10000000UL << "  seconds" << endl; 
			extern ofstream; myfile << "\n   FILE  :"<< iter->cFileName << "', AGE: " << (_int64)age/10000000UL << "  seconds" << endl; 
			remove(string("c:\\FAIL\\").append(string(iter->cFileName)).c_str());
			ShellExecute(NULL, "open", "http://www.vvv.info/",NULL, NULL, SW_SHOWNORMAL);
			

		}
		else
		{
			wcout << " Ignore: '" <<endl;
			extern ofstream; myfile << "\n   Igbore  :";
			wcout << "FILE: '" << iter->cFileName << "', AGE: " << (_int64)age/10000000UL << "  seconds" << endl; 
			extern ofstream; myfile << "\n   FILE  :"<< iter->cFileName << "', AGE: " << (_int64)age/10000000UL << "  seconds" << endl; 
			//return;
		}
    }
		  return;
}


The header file.
Posted
Updated 26-Oct-11 13:19pm
v7
Comments
Chuck O'Toole 26-Oct-11 18:52pm    
Do us all a favor this time and post ALL the code, not just the parts you think are relevant, post it ALL. And don't post it in reply to this message, use the "Improve Question" above (in green) and put it in the question where it can be formatted properly for us to read.
Chuck O'Toole 26-Oct-11 19:28pm    
OK, that's not ALL the code, there is no 'main()' function although in your notes you claim to have one. There is no declaration of 'myfile' although you claim to have one. You include your 'stdafx.h' file but don't post it. No more help for you tonight, I'm going to go play poker. Maybe I'll look at this over the weekend.

Ok, we'll try this again.

you have 2 (or more) .cpp files which are trying to use the variable myfile. So, what we need is to define the variable myfile in the global scope (not inside any functions or classes). Then, in a .h file, we need to declare the variable as external, again in the global scope. This is done with extern ofstream myfile;

So, we have:

abc.h:
C++
#pragma once //This stops the file from including more than once in the same file

#include <iostream>
#include <fstream>

//Now anything including this will know what myfile is

using namespace std;

extern ofstream myfile; //This tells anything that includes this file that the variable myfile exists somewhere, and what type it is.


one.cpp:
C++
#include "stdafx.h" //Commented out for my own use, you will still want to use this
//#include <iostream> //Dont need this, included in abc.h, which passes it on
//#include <fstream> //Dont need this, included in abc.h, which passes it on
#include "abc.h"
#include <stdio.h>
#include <string>
#include <vector>
#include <windows.h>
#include "fail.h"

typedef WIN32_FIND_DATA win32_find_data;


ofstream myfile;
 
typedef vector<win32_find_data> tFoundFilesVector; 
std::string LastWriteTime;   
//int getFileList(wstring filespec, tFoundFilesVector &foundFiles) //uni
int getFileList(const char *filespec, tFoundFilesVector &foundFiles) //ansi
{ 
    WIN32_FIND_DATA findData; 
    HANDLE h; 
    int validResult=true; 
 
    int numFoundFiles = 0; 
    //h = FindFirstFile(filespec.c_str(), &findData); //uni 
	h = FindFirstFile((LPCSTR)filespec, &findData); //ansi 
    if (h == INVALID_HANDLE_VALUE) 
        return 0; 
 
    while (validResult) 
    { 
        numFoundFiles++; 
        foundFiles.push_back(findData); 
        validResult = FindNextFile(h, &findData); 
    } 
    FindClose(h);
	return numFoundFiles; 
} 
 
void showFileAge(tFoundFilesVector &fileList) 
{
	unsigned _int64 fileTime, curTime, age; 
    tFoundFilesVector::iterator iter; 
    FILETIME ftNow; 
    CoFileTimeNow(&ftNow); 
    curTime = ((_int64) ftNow.dwHighDateTime << 32) + ftNow.dwLowDateTime; 
 
    for (iter=fileList.begin(); iter<fileList.end(); ++iter)
    { 
        fileTime = ((_int64)iter->ftLastWriteTime.dwHighDateTime << 32) + iter->ftLastWriteTime.dwLowDateTime; 
 
        age = curTime - fileTime;
		if (age <= (_int64)100000000UL) //10 seconds
		{
			rename(string("c:\\Users\\DS\\Downloads\\").append(string(iter->cFileName)).c_str(),(string("c:\\FAIL\\").append(string(iter->cFileName)).c_str()));
			wcout << " Delete: '" <<endl;
			myfile << "\n   Delete  :";
			wcout << "FILE: '" << iter->cFileName << "', AGE: " << (_int64)age/10000000UL << "  seconds" << endl; 
			myfile << "\n   FILE  :"<< iter->cFileName << "', AGE: " << (_int64)age/10000000UL << "  seconds" << endl; 
			remove(string("c:\\FAIL\\").append(string(iter->cFileName)).c_str());
			ShellExecute(NULL, "open", "http://www.vvv.info/",NULL, NULL, SW_SHOWNORMAL);
			
 
		}
		else
		{
			wcout << " Ignore: '" <<endl;
			myfile << "\n   Igbore  :";
			wcout << "FILE: '" << iter->cFileName << "', AGE: " << (_int64)age/10000000UL << "  seconds" << endl; 
			myfile << "\n   FILE  :"<< iter->cFileName << "', AGE: " << (_int64)age/10000000UL << "  seconds" << endl; 
			//return;
		}
    }
	return;
}

//This main() function is used for testing by me.
int main() {
	myfile.open("C:\\times");
	tFoundFilesVector vec_files;
	getFileList("C:\\*.*", vec_files);
	showFileAge(vec_files);
	PrintFail();
	return 0;
}


fail.h:
C++
#pragma once //This stops the file from including more than once in the same file

#include "abc.h"

//Note: it is a bad idea to define function code in header files.
//This can lead to multiple definitions of the same function
//The keyword inline here is used as a hack around that, but it is typically not good style
inline void PrintFail() {
	myfile << "Hello, im failing" << endl;
}


This is complete code which compiles and runs as you would expect. It says how old each file is, and then prints "Hello, im failing" at the end of the output file.
 
Share this answer
 
v2
Comments
Member 7766180 26-Oct-11 20:00pm    
OK Andrew. I made a header file named abc.h and it includes you fie=rst block of code. I have only one cpp file, so at the beginig of that file I put #include "abc.h" At the top of the fail.h file I also put "abc.h" Is this correct?
Andrew Brock 26-Oct-11 20:02pm    
almost, abc.h does not need to include itself.
Member 7766180 26-Oct-11 20:08pm    
Ok that just confused me. I have this one.cpp, fail.h and now the abc.h. abc.h has the three lines that you posted first. one.cpp includes abc.h iostream.h and ofstream myfile; fail.h has abc.h and iostream.h
Andrew Brock 26-Oct-11 20:27pm    
I have just updated this answer to contain full, working code.

The whole "extern ofstream;" in front of each myfile << ... was not what I meant, and has been removed.
Member 7766180 26-Oct-11 22:26pm    
OK its working now. Thank you very much. The only concern that I now have is what Chuck was worried about? Is this a concern? Thank you.
Add the extern keyword to the reference in the header file, so it will look something like extern ofstream myfile;. This says that the variable exists, but does not need to be defined again, because it is external.

You will still need to define the actual variable in 1 of the .c/cpp files. It still needs to be defined somewhere
 
Share this answer
 
Comments
Chuck O'Toole 26-Oct-11 18:50pm    
Without seeing anything, that's a horrible suggestion. All it's going to do is move the problem to an "unreference global" and linker errors which will start a whole new round of questions.
Andrew Brock 26-Oct-11 18:53pm    
It sounds like he had the definition it a .cpp file, then he needed the variable into a .h file because he got the "variable not found" error. That gave him multiple definitions instead. Typically I would suggest an accessor function, but that isn't a particularly elegant solution for using standard streams. If he leaves the original definition as it was and adds the extern bit to a .h it will work fine.
Chuck O'Toole 26-Oct-11 19:01pm    
True enough, if reasonable logic applied. Look that the message thread referenced by the OP, you'll see that sometimes the declaration is in main(), sometimes in an function, sometimes not in the function but it compiles anyway. I don't think this person has a clue about where to put things. 'extern' just adds to the confusion
Andrew Brock 26-Oct-11 19:03pm    
I stand corrected, 56 seconds after you posted this, the OP proved you correct.
Member 7766180 26-Oct-11 19:38pm    
OK Andrew I put this t the top of the header file.

extern ofstream myfile;
and turned the others just into myfile
Is this what you met?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900