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;
}