--------------------------------------------------------------------------------

Hey all. I'm a newbie at C++ and hope that you guys can guide me along. I recently got assigned a project and is needed to code it in C++, which I have almost zero experience with, so bear with me. =)

I need to delete 3 log files from a particular location. The name of the 3 files include (name + date + extension)where the name could be changed in a particular ini file named "config.ini". The configuration file look something like this:

[config]
PATH = C:\\Test\\
LOG1 = ABC
LOG2 = XYZ
DB = DATA

LOG1 and LOG2 needs to be on yesterday's date. An example would be "ABC090420.txt". DB needs to be the date when it was eight days ago.

I want to be able to change the path where the file is located and the name of the files at will in the "config.ini". Whether the files are deleted or not, it will be recorded in a newly created text file "LogDelete.txt". The program will run once every week, which means the "LogDelete.txt" will keep appending data without overwriting previous weeks' record.

I have completed the date part (getting yesterday and eight days ago date) and the "LogDelete.txt" thanks to Google =).

My request now is to have someone guide me along as to what I am suppose to do and give me a brief idea of how the syntax of each particular steps will look like. I am not asking for anyone to write the entire code for me, because I want to learn this and do it by my own effort if possible.

I am currently running on Windows XP and using Dev-C++.

If anyone wants a sample of how the program looks like, I have a jar file which I have completed previously but got rejected. You need java runtime to run the jar file. Attachment is below.

Advice or input appreciated, and thanks for taking your time to read this long post. Below is what I have gotten thus far:

#include <ctime>
#include <iostream>
#include <fstream>
#include <Windows.h>


using namespace std;

int main(int argc, char *argv[])
{
    time_t today, ytd, eightDays, currTime;
    struct tm * timeinfo;
    int year, month, day;
    char yest [10];
    char eight [10];
    time (&currTime);

    cout << ctime(&currTime) << endl;
    
    time( &today );
    timeinfo = localtime ( &today );
    
    ytd = today - 86400;
    timeinfo = localtime (&ytd);
    strftime (yest, 10, "%y%m%d", timeinfo);
    
    eightDays = today - 691200;
    timeinfo = localtime (&eightDays);          
    strftime (eight, 10, "%y%m%d", timeinfo);
             
    cout << "Yesterday = " << yest << endl;
    cout << "Eight Days ago = " << eight << endl;
        
    
    FILE * aFile;
    
    aFile = fopen("LogDelete.txt", "a+");
    
    if (aFile!=NULL) {

         ofstream aFile ( "LogDelete.txt", ios::app );
         aFile << "Program run time: " << ctime(&currTime) << endl;
         aFile.close();    
    }

    cin.get(); 
    return 0;

}

This :

FILE * aFile;
    
    aFile = fopen("LogDelete.txt", "a+");
    
    if (aFile!=NULL) {

         ofstream aFile ( "LogDelete.txt", ios::app );
         aFile << "Program run time: " << ctime(&currTime) << endl;
         aFile.close();    
    }

is.. well.. ugly ;) The good thing is that you understand that you need to check if the file exists before opening it. But you are using a combination of C and C++ (more or less), and you're trying to open the file two times at once. How about something like:

ofstream aFile ( "LogDelete.txt", ios::app );
if (aFile.is_open() && aFile.good()) {
    aFile << "Program run time: " << ctime(&currTime) << endl;
    aFile.close(); 
}

The next step in you program should be to parse the inifile. Do you have specification on what format the file will have, or will it always look exactly like the example you posted?

Ah ok. Thanks for the clarification. I was just roaming around google for the "LogDelete.txt" part and just put the pieces that I found together. :P

What do you mean by "parse the inifile"?
The format for the inifile that I posted is exactly the same that I want. The code should not create the inifile, but rather read from it since the file was created by me.

Also, I have searched regarding on "how to check if file exists in C++" and most of the solutions recommend opening the file. I feel that it is rather inefficient, since I do not know how big the log files are. Deleting a thousand files using that method might be a chore too...

To parse your file (to get all the data), you need to read it in one line at a time and then look
- what info is on that line
- what value it has
- store it somewhere

Here's something to get you started:

ifstream aFile ( "LogDelete.txt"); // input
if (aFile.is_open() && aFile.good()) { // all ok, start reading
    string str = "";
    while (getline(aFile, str)){
         cout << "a line: " << str << "\n";
    }
}

Hmm wait a minute...let me clarify something.

The configuration file "config.ini" is the file that I want to read data from.
The file "LogDelete.txt" is the text file I want to first, create, and then subsequently append text to every week when I delete my "LOG1, LOG2 and DB" files as stated in my "config.ini".

Just checking - are we on the same page? :)

Just checking - are we on the same page? :)

Absolutely not :)
But my advice still works. You need to parse your ini file to find out which files you need to delete. So use my previously posted code and change LogDelete.txt to 'config.ini'. Now it will run through each line in your config.

The next step you need to take, is figure out how to find the names of the file. Here's a link that will come in handy

Awesome. Thanks.

The code that you post works. I tried to change it a little by using the method as mentioned in the link you provided, but got a funny "Visual Studio Just-In-Time Debugger" Window with the error message "An unhandled win32 exception occurred in xxx.exe[random 4-digit number]" popping up everytime I try to run the project.

config.ini

PATH = C:\Test\
LOG1 = ABC
LOG2 = XYZ
DB = DATA
void SplitFilename (string& str)
{
  size_t found;
  found=str.find_last_of(" = ");
  cout << "Value found: "<< str.substr(found+1) << endl;
}

    ifstream cFile ("config.ini");
    if (cFile.is_open() && cFile.good()) {
       int i = 0;
       string strz[] = "";
       while (getline(cFile, strz[i])) {
           cout << strz[i] << endl;
           string show (strz[i]);
           SplitFilename (show);
           i++;
           
       }
    }
    cFile.close();

Also, what do all these code means?

size_t find ( const string& str, size_t pos = 0 ) const;
size_t find ( const char* s, size_t pos, size_t n ) const;
size_t find ( const char* s, size_t pos = 0 ) const;
size_t find ( char c, size_t pos = 0 ) const;

You have a flaw in your code:

string strz[] = "";// <--- What??
       while (getline(cFile, strz[i])) {// <-- oh-oh writing in undefined memory

What are you trying to do anyway? Do you want to store each line from the file in the memory? That's not really nescessary, you could do something like:

ifstream cFile ("config.ini");

    if (cFile.is_open() && cFile.good()) {
       string strz = "";
       while (getline(cFile, strz)) {
           cout << strz << endl;
           SplitFilename (strz);           
       }
    }
    cFile.close();

If you do want to store all the lines, you could use a vector of strings.

Hmm...I was trying to read the last string from each line and store it somewhere so I can retrieve it and append it to the file names that I am going to delete.(wow long sentence. i hope that makes sense)

Basically, the 3 files that I am going to delete will consists of 3 parts:
1) The value in "LOG1, LOG2 and DB" in "config.ini".
2) Yesterday's and eight days ago's date.
3) The extension ".txt".

Say if my "config.ini" file looks like this, with today's date being 22/4/2009:

PATH = C:\Test\
LOG1 = ABC
LOG2 = XYZ
DB = DATA

the file names will look exactly like this:
ABC090421.txt
XYZ090421.txt
DATA090414.txt

This article has been dead for over six months. Start a new discussion instead.