PDA

View Full Version : C programming help


Khiempossible
05-11-2006, 02:16 AM
So I'm a first year civil engineering student. Haha. K. Then I lucked into this programming job in Switzerland. My boss has every understanding I'm a very beginner programmer. Anyways, i'm trying to develop a program that searches log files by date and outputs only the pieces of the log file of interest. Logfiles are dated by timestamps (Unix based) which are numbers. These numbers represent the number of seconds that have passed since jan 1 1970. Anyways, I need my user to input the date in standard form. dd/mm/yyyy hh:mm:ss and I need it to convert to timestamp form so I can search my logfiles.

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<time.h>

/* ----------------------------------------------------------------------------
** Static Function Prototypes - necessity for conversion
*/
static time_t convert (char *buff);
static int convertMonth (char *mon);
static void showFormats (void);


/* ----------------------------------------------------------------------------
** Constant Definitions - necessity for conversion
*/
#define DATE_FORMAT_SPEC "%d %s %d %d:%d:%d" /* 25 Aug 2004 13:30:00 */
#define DATE_FORMAT_SPEC2 "%s %d %d:%d:%d %d" /* Aug 25 13:30:00 2004 */
#define DATE_FORMAT_SPEC3 "%s %s %d %d:%d:%d %d" /* Wed Aug 25 13:30:00 2004 */
#define DATE_FORMAT_SPEC4 "%d/%d/%d %d:%d:%d" /* 25/08/2004 13:30:00 */


/* ----------------------------------------------------------------------------
** Convert month string to integer - necessity for conversion
** Returns : -1 -> no match found, other ->
*/
static int convertMonth (char *mon)
{
char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
int i;

/* search for match */
for (i=0; i<12; i++) {
if (!strcasecmp (months[i], mon)) {
break;
}
}

if (i == 12) {
return (-1);
}
return (i);
}


//conversion function stolen from time2int
static time_t convert (char *buff)
{
struct tm tmval;
char mon[16], day[16];
time_t tval;
int c, monval;

/* initialisation */
memset(&tmval, 0, sizeof(struct tm));
strcpy (day, "");
strcpy (mon, "");
tval = -1;

/* scan date fields from buffer */
if ( ((c = sscanf (buff, DATE_FORMAT_SPEC,
&tmval.tm_mday, mon, &tmval.tm_year,
&tmval.tm_hour, &tmval.tm_min, &tmval.tm_sec)) == 6) ||
((c = sscanf (buff, DATE_FORMAT_SPEC2,
mon, &tmval.tm_mday, &tmval.tm_hour, &tmval.tm_min,
&tmval.tm_sec, &tmval.tm_year)) == 6) ||
((c = sscanf (buff, DATE_FORMAT_SPEC3,
day, mon, &tmval.tm_mday, &tmval.tm_hour, &tmval.tm_min,
&tmval.tm_sec, &tmval.tm_year)) == 7) ||
((c = sscanf (buff, DATE_FORMAT_SPEC4,
&tmval.tm_mday, &tmval.tm_mon, &tmval.tm_year,
&tmval.tm_hour, &tmval.tm_min, &tmval.tm_sec)) == 6) ) {

/* try to convert month string */
monval = convertMonth (mon);
if (monval != -1) {
tmval.tm_mon = monval;
} else {
/* month was supplied as integer in buffer */
tmval.tm_mon -= 1;
}

/* perform conversion */
tmval.tm_isdst = -1;
tmval.tm_year -= 1900;
if ((tval = mktime (&tmval)) == -1) {
printf ("failed to mktime()\n");
return (-1);
}
}

return (tval);
}


int main()
{
for(;;)
{
FILE *fp; //file pointer
int i=0, j=0, k=0, l=0;
char filename[30], date1[10], date2[10], time1[10], time2[20], temp1[20], temp2[20], *temp1p, *temp2p;
time_t t1, t2;

//retrieving data
scanf("%s %s %s %s %s", filename, date1, time1, date2, time2);

if(filename[0]==0)
{
//bring up help documentation
}
else
{//exit clause
if((filename[0]=='e')&& (filename[1]=='x') && (filename[2]=='i') && (filename[3]=='t'))
{
exit(1);
}
else
{
printf("data is: %s %s %s %s %s\n", filename, date1, time1, date2, time2);

strcpy(temp1, " ");
strcpy(temp2, " ");

for(;date1[i]!='\0';i++)
{
temp1[i] = date1[i];
printf("%s\n", temp1);
}
temp1[i] = ' ';
printf("%s\n", temp1);

j=i+1;
for(; time1[j-i-1]!='\0';j++)
{
temp1[j] = time1[j-i-1];
printf("%s\n", temp1);
}

for(;date2[k]!='\0';k++)
{
temp2[k] = date2[k];
printf("%s\n", temp2);
}
temp2[k] = ' ';
printf("%s\n", temp2);
l=k+1;
for(; time2[l-i-1]!='\0';l++)
{
temp2[l] = time2[l-i-1];
printf("%s\n", temp2);
}

printf("\n%s\n", temp1);
printf("%s\n", temp2);

*temp1p = &temp1;
*temp2p = &temp2;

t1 = convert(temp1p);
t2 = convert(temp2p);

printf ("%d %d", (int) t1, (int) t2);

printf("data is: %s %s %s %s %s\n", filename, date1, time1, date2, time2);

//opening file and checking errors
if((fp=fopen(filename,"r"))==NULL)
{
printf("Cannot open file\n");
exit(1);
}
}
}
}
return 0;
}

that's my program. The first two functions my boss gave me in a program that converts real dates to timestamps (because there are no functions like this in a C library. Clearly the program is unfinished.

anyways, on to my problem. I don't exactly understand how the first two functions work. I assume they do since, I copied them directly from the source code of the time2int program. I kinda get the gist of it. the convert function takes a string pointer and returns the time value in a new variable type called time_t. I think.

Anyways, the specific problem for the moment is:

*temp1p = &temp1;
*temp2p = &temp2;

i'm trying to create a pointer of for the strings containing my real dates so that I can feed them to my convert function.

I get the following warnings:

assignment makes integer from pointer without a cast 159
assignment makes integer from pointer without a cast 160

I'm not sure if my pointers are working properly, I debug, and I believe i'm getting an address for my pointers. But when I feed it to my function I get -1 for my t1 and t2 variables which are supposed to be integers or a long series of numbers representing my timestamps. I think the problem lies there. help s'il te plait. thanks.

here's the time2int program I was given.

/* ----------------------------------------------------------------------------
** Program : time2Int.c
** Description : Convert a time string into an integer.
** ------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------------
** Standard headers
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <time.h>


/* ----------------------------------------------------------------------------
** Static Function Prototypes
*/
static time_t convert (char *buff);
static int convertMonth (char *mon);
static void showFormats (void);


/* ----------------------------------------------------------------------------
** Constant Definitions
*/
#define DATE_FORMAT_SPEC "%d %s %d %d:%d:%d" /* 25 Aug 2004 13:30:00 */
#define DATE_FORMAT_SPEC2 "%s %d %d:%d:%d %d" /* Aug 25 13:30:00 2004 */
#define DATE_FORMAT_SPEC3 "%s %s %d %d:%d:%d %d" /* Wed Aug 25 13:30:00 2004 */
#define DATE_FORMAT_SPEC4 "%d/%d/%d %d:%d:%d" /* 25/08/2004 13:30:00 */


/* ----------------------------------------------------------------------------
** Convert month string to integer
** Returns : -1 -> no match found, other ->
*/
static int convertMonth (char *mon)
{
char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
int i;

/* search for match */
for (i=0; i<12; i++) {
if (!strcasecmp (months[i], mon)) {
break;
}
}

if (i == 12) {
return (-1);
}
return (i);
}


/* ----------------------------------------------------------------------------
** Perform conversion
** Returns : -1 -> error, other -> time as time_t
*/
static time_t convert (char *buff)
{
struct tm tmval;
char mon[16], day[16];
time_t tval;
int c, monval;

/* initialisation */
memset(&tmval, 0, sizeof(struct tm));
strcpy (day, "");
strcpy (mon, "");
tval = -1;

/* scan date fields from buffer */
if ( ((c = sscanf (buff, DATE_FORMAT_SPEC,
&tmval.tm_mday, mon, &tmval.tm_year,
&tmval.tm_hour, &tmval.tm_min, &tmval.tm_sec)) == 6) ||
((c = sscanf (buff, DATE_FORMAT_SPEC2,
mon, &tmval.tm_mday, &tmval.tm_hour, &tmval.tm_min,
&tmval.tm_sec, &tmval.tm_year)) == 6) ||
((c = sscanf (buff, DATE_FORMAT_SPEC3,
day, mon, &tmval.tm_mday, &tmval.tm_hour, &tmval.tm_min,
&tmval.tm_sec, &tmval.tm_year)) == 7) ||
((c = sscanf (buff, DATE_FORMAT_SPEC4,
&tmval.tm_mday, &tmval.tm_mon, &tmval.tm_year,
&tmval.tm_hour, &tmval.tm_min, &tmval.tm_sec)) == 6) ) {

/* try to convert month string */
monval = convertMonth (mon);
if (monval != -1) {
tmval.tm_mon = monval;
} else {
/* month was supplied as integer in buffer */
tmval.tm_mon -= 1;
}

/* perform conversion */
tmval.tm_isdst = -1;
tmval.tm_year -= 1900;
if ((tval = mktime (&tmval)) == -1) {
printf ("failed to mktime()\n");
return (-1);
}
}

return (tval);
}


/* ----------------------------------------------------------------------------
** Show valid date & time formats
*/
static void showFormats (void)
{
printf ("Valid formats :-\n");
printf (" 25 Aug 2004 13:30:00,\n");
printf (" Aug 25 13:30:00 2004,\n");
printf (" Wed Aug 25 13:30:00 2004,\n");
printf (" 25/08/2004 13:30:00\n");

}

/* ----------------------------------------------------------------------------
** Main
*/
int main (int argc,
char *argv[])
{
char buff[64], *c_p;
time_t tval;
int i;

/* convert args if present */
if (argc > 1) {
strcpy (buff, "");
for (i=1; i<argc; i++) {
strcat (buff, argv[i]);
strcat (buff, " ");
}
if ((tval = convert (buff)) == -1) {
printf ("Error : failed to convert time '%s'\n", buff);
showFormats();
} else {
printf ("%d\n", (int) tval);
}
} else {
/* interactive mode */
while (1) {
printf ("time string : ");
c_p = gets(buff);
if (c_p) {
if ((tval = convert (c_p)) == -1) {
printf ("Error : failed to convert time '%s'\n", c_p);
showFormats();
} else {
printf ("time as int = %d\n", (int) tval);
}
}
printf ("\n");
fflush (stdout);
}
}
exit (0);
}

Lastly, I'm programming in Eclipse with the CDT plug-in on WinXP with the GCC compiler from cygwin.

hlam
05-11-2006, 02:28 AM
well, i just took a course to computers & programming in C and without looking hard at your code, there's an easy fix for your two warnings.

you've already declared the two pointers, but once you put a * in front of them, that tells the compiler to modify the value of the pointer's address.

So you can easily fix the two problems by removing the *'s in front of both lines of code and set the pointer = &temp1[0]; this sets the pointer to point to the first value in the temp1 array. you can also do temp1p = temp1;

that should solve your warning problems thus far, but the hard part of testing and debugging still lies ahead. Good luck!

Khiempossible
05-11-2006, 03:30 AM
you're right. the * in front of my pointers when I declare them fucks it up, however it leaves me with a different error that goes something like:

pointer assigned to illegal type or something. so then I did some reading, and arrays are actually just pointers. so I took out my pointer declarations and simply plugged my strings into the function and now I get numbers. wow. what an easy solution.I think i'll leave this up here, cause I'm bound to find more errors I have no clue how to fix. Thanks for the help though.

Actually, my current issue is getting reading my files line by line. For this I'm going to have to read a lot more stuff, unless someone here knows how to open a file and then read the file line by line.

Yeah, let me elaborate.

my logfile is something like 2 million lines long. It's huge.

I want to search through the file and look at the timestamps. My user inputs two timestamps. I then want to output every line between the two timestamps, so that my user only has to analyze the data between the timestamps he's interested in (say something funny is going on between these times).

now the only way i know how to use the function fscanf is to assign every string in the file to a variable, which is stupid.

does anyone know a better way?

selfscience
05-11-2006, 08:21 AM
Actually, my current issue is getting reading my files line by line. For this I'm going to have to read a lot more stuff, unless someone here knows how to open a file and then read the file line by line.


I didn't look at your code because I'm lazy, but if you want to loop through the file line by line, just do the following:


char buf[1024];
FILE *fdin;
fdin = fopen( whatever your file is, "r");

while (0 != fgets (buf, 1024, fdin))
{
//do whatever with buf
}

buf will contain each line so you can do comparisons, output...etc.

UltraScrub
05-11-2006, 06:41 PM
Does this program have to be written in C?

I'm not quite sure about the format of the file. Are you saying the timestamps are in the text of the log file, or is it the timestamp of the log file itself?

Etcetera
05-11-2006, 07:00 PM
you're right. the * in front of my pointers when I declare them fucks it up, however it leaves me with a different error that goes something like:

pointer assigned to illegal type or something. so then I did some reading, and arrays are actually just pointers. so I took out my pointer declarations and simply plugged my strings into the function and now I get numbers. wow. what an easy solution.I think i'll leave this up here, cause I'm bound to find more errors I have no clue how to fix. Thanks for the help though.

Actually, my current issue is getting reading my files line by line. For this I'm going to have to read a lot more stuff, unless someone here knows how to open a file and then read the file line by line.

Yeah, let me elaborate.

my logfile is something like 2 million lines long. It's huge.

I want to search through the file and look at the timestamps. My user inputs two timestamps. I then want to output every line between the two timestamps, so that my user only has to analyze the data between the timestamps he's interested in (say something funny is going on between these times).

now the only way i know how to use the function fscanf is to assign every string in the file to a variable, which is stupid.

does anyone know a better way?
I am a little confused on what the probelm is, seems like you know what to do. I didn't read all of the code either (I am lazy like everyone else in this thread), but If you are looking into outputing the lines between timestamps in this log file, your best bet would be to create a buffer array for the line following the stamp after you do a compare for each line to see if you have to output the line, just like what selfscience was doing.
Is it just the code giving trouble, or just at a lost as to what to do?

Pimp Willy
05-11-2006, 07:18 PM
Maybe use an FStream class?

http://www.cplusplus.com/ref/iostream/fstream/
#include <fstream>

ifstream File("WhateverLog.log");
string currentLine;

while (!File.eof())
{
File.getline(currentLine, 2000); //change 2000 to a number based on how long the logfiles are
//do your comparisons with currentLine, which has the next line in the log
// i.e. check it against timestamps and output if so
}

File.close();

Khiempossible
05-15-2006, 01:24 AM
Haha, thanks for the help guys. I endup using fgets and a for loop to run through my data.

I am now wondering if anyone has a clue how to set up getopt in C. Instead of running the program and then inputting the data, I think it would be better to have all the data inputted as options and to output a helpfile if no options are selected.