Hello all,

I'm having a problem with my program when I try to compile it. It shows the message in the thread title along with a method it doesn't like: extensionRemover(). I've Googled the problem but they were all related to the header file and use of multiple classes.

Where this method is called is line 158, with in processTags(). Simpley commenting this line out solves the problem, but I can't see why the complier doesn't like this method. As you can see, I've just started using C++ but I normally dabble in Java (waiting for a book to arrive so I can make this program less procedural and more OO).

If anyone can help it would be most appreciated! Comments on program structure etc are also welcome (I know it's a bit of a novice job!)

Thanks

/**
 * HeaderToXML.cpp
 * Take a .gts file as input.  Reads the header and outputs header values into XML.  Saved to an XML file.
 * 
 * Date: 6.7.2010
 */

#include "stdafx.h"
#pragma warning(disable: 4786)
#include <io.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <list>
using namespace std;


/*Structure to hold a directory and all its filenames.*/
struct FILELIST
{
	string filePath;
	vector<string> fileNameList;
};


/**##########trim(string)##########
 * Removes the leading and trailing spaces from a string
 * 
 * @param inputString		The string that needs the white spaces removed.
 * @return					The truncated string
 */
string trim(string inputString){
    string whiteSpace = " \t";
	size_t beginStr = inputString.find_first_not_of(whiteSpace);
    
	if (beginStr == string::npos){
        // no content
        return "";
    }

    size_t endStr = inputString.find_last_not_of(whiteSpace);
    size_t range = endStr - beginStr + 1;

    return inputString.substr(beginStr, range);
}





/**##########transverseDirectory(string, list<FILELIST>)##########
 * Recursively goes through files and sub-directories
 * 
 * @param xmlFile	- Reference to open file stream.  Ready to be written to.
 * @param tag		- XML tag.
 * @param value		- XML value.
 */
void transverseDirectory(string path, list<FILELIST> &theList){
	
	struct _finddatai64_t data;
	string fname = path + "\\*.*";
	long h = _findfirsti64(fname.c_str(),&data);
	
	if(h >= 0){
		FILELIST thisList;
		// add empty FILELIST structure to the linked list argument
		theList.push_back(thisList);
		// get pointer to the FILELIST just added to the linked list above.
		list<FILELIST>::iterator it = theList.end();
		it--;
		// set current path
		(*it).filePath = path;
		do {
			if( (data.attrib & _A_SUBDIR) )
			{
				// make sure we skip "." and "..".  Have to use strcmp here because
				// some file names can start with a dot, so just testing for the 
				// first dot is not suffient.
				if( strcmp(data.name,".") != 0 &&strcmp(data.name,"..") != 0)
				{
					// We found a sub-directory, so get the files in it too
					fname = path + "\\" + data.name;
					// recursion here!
					transverseDirectory(fname,theList);
				}

			}
			else{
				// this is just a normal filename.  So just add it to our vector
				(*it).fileNameList.push_back(data.name);

			}
		}while( _findnexti64(h,&data) == 0);
		// close the find handle.  
		_findclose(h);

	}

}


/**##########collectFileNames(vector<string>)##########
 * Calls the transverseDirectory() method to gather file names. Stores them in a list of strings
 *
 * @param &filePaths	- Reference to the string vector that is storing the file names
 */
void collectFileNames(vector<string> &filePaths){
	
	list<FILELIST> MyList;
	string path;
	cout << "Enter starting path ... ";
	getline(cin,path);
	transverseDirectory(path,MyList);
	list<FILELIST>::iterator it;

	for(it = MyList.begin(); it != MyList.end(); it++)
	{
		vector<string>::iterator its;
		for(its = (*it).fileNameList.begin(); its != (*it).fileNameList.end(); its++){
			string fileName =  *its;
			int index_gts = fileName.find(".gts");
			int index_xml = fileName.find(".xml");
			if(index_gts == string::npos || index_xml != string::npos){
				continue;
			}else{
				filePaths.push_back((*it).filePath + "\\" + (*its));
			}
		}
	}
}


/**##########checkFirstLine(string)##########
 * Checks whether the file being read has a valid header
 *
 * @param inputLine	- First line of the file.
 * @return			- 'true' if header is valid, 'false' if not.
 */
string checkFirstLine(string inputLine){
	
	int index = inputLine.find("TS_INFOTEXT"); 
	if (index != string::npos){
		inputLine = "true";
		return inputLine;
	}else{
		inputLine = "false";
		return inputLine;
	}
}


void processTags(vector<string> &xmlTags, string currentFilePath){
	string inputLine, firstLineTester, part1, part2, tag, value, fileName;
	size_t pos;

	ifstream currentFile(currentFilePath);
	fileName = extensionRemover(currentFilePath);		//<---Problem!
	if (currentFile.is_open()){	
		getline (currentFile,inputLine);
		firstLineTester = checkFirstLine(inputLine);
			
		if(firstLineTester == "false"){
			return;
		}else{
			currentFile.seekg(0);							//Resets the pointer to go back to the beginning of the file
			xmlTags.push_back("<" + fileName + ">\n");

			while (!currentFile.eof()){
				getline (currentFile,inputLine);
				
				if(inputLine == ""){
					continue;
				}
				pos = inputLine.find(":");
				part1 = inputLine.substr (0,pos);
					
				if(part1 == "START_OF_TRANSPORT_STREAM"){
					break;
				}
				part2 = inputLine.substr (pos+1);
				tag = trim(part1);
				value = trim(part2);
				xmlTags.push_back("\t<" + tag + ">" + value + "</" + tag + ">" + "\n");
			}
		}
	}
	xmlTags.push_back("</" + fileName + ">");
	currentFile.close();
}


/**##########writeToFile(ofstream, string, string)##########
 * Writes the XML tag and value to file
 * 
 * @param xmlFile	- Reference to open file stream.  Ready to be written to.
 * @param tag		- XML tag.
 * @param value		- XML value.
 */
void writeToFile(string filePath, vector<string> xmlTags){

	ofstream xmlFile(filePath + ".xml");
	if(xmlFile.is_open()){
		for(int i = 0; i < xmlTags.size(); i++){
			xmlFile << xmlTags[i];
			cout << xmlTags[i];
		}
		xmlFile.close();
	}else{
		cout << "Unable to open XML file for Writing";
	}
}


string extensionRemover(string filePath){		//<---Problem method!
	
	size_t pos = filePath.find_last_of("\\");		
	string fileName = filePath.substr(pos+1);	// Holds the fileName + extension
	pos = fileName.find_first_of(".");				
	fileName = fileName.substr(0,pos);			// Holds the fileName + extension
	return fileName;
}


int main (){
	vector<string> filePaths;
	collectFileNames(filePaths);				// Method call to collect file names in directories
	
	for(int i = 0; i < filePaths.size(); i++){
		vector<string> xmlTags;
		processTags(xmlTags,filePaths[i]);		// Method call to create XML tags and values
		if(xmlTags.empty()){
			continue;							
		}else{
			ofstream xmlFile(filePaths[i] + ".xml");
			writeToFile(filePaths[i], xmlTags);
		}	
	}				
cout << "All Done";
cin.get();
return 0;
}

Recommended Answers

All 2 Replies

You are attempting to call the function before it comes into scope. To fix this, you need to add prototypes for your functions to the top of your file.

//******
//***THIS EXAMPLE CONTAINS AN ERROR AND WILL NOT COMPILE/LINK
//******
// the function someFunction has not come into scope
int main() {
  //someFunction is still not in scope
  someFunction(); //ERROR: someFunction is not in scope
  return 0;
}

//someFunction is still not in scope
void someFunction() { //define someFunction, someFunction is finally in scope
  cout << "In someFunction()..." << endl;
}
//someFunction is still in scope
//...
//******
//***THIS EXAMPLE CORRECTS THE ABOVE ERROR AND SHOULD COMPILE/LINK
//******
// the function someFunction has not come into scope
void someFunction(); //prototype of someFunction, it is now in scope, but not defined

int main() {
  //someFunction is in scope, but not defined
  someFunction(); //NOW WORKS: someFunction is in scope, but not defined
  return 0;
}

//someFunction is still in scope, but not defined
void someFunction() { //define someFunction, it is still in scope
  cout << "In someFunction()..." << endl;
}
//someFunction is still in scope and is now defined
//...

Notice the differences between the 2 examples.

Of course!! Thank you very much

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.