So I have two programs in their entirety.
DateValidater.c
Code:
#include <stdio.h>
#include <stdlib.h> /*To be able to use the #define constant EXIT_SUCCESS*/
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>
#include "Dates.h"
#define BASE 10
#define NOTVALIDENTRY -1
#define DELIMITER "/"
#define FOUR 4
#define ONEHUNDRED 100
#define FOURHUNDRED 400
#define MAXCHARS 80
#define MAXLINES 256
int getNumOfEntries(char *);
void getDates(char [MAXLINES][MAXCHARS], int *, int);
int checkDate(char []);
const char *parseDate(const char *, int *, const char *);
int isValidDate(int, int, int);
void sendAllDates(char [MAXLINES][MAXCHARS], int);
int isLeapYear(int);
typedef enum {FALSE, TRUE} Bool;
int main(int argc, char *argv[])
{
int numOfEntries = 0;
int numOfLines = 0;
char dates[MAXLINES][MAXCHARS];
numOfEntries = getNumOfEntries(argv[1]);
if(numOfEntries < 0)
{
puts("You have either enter an entry too small, too big or");
puts("an entry that is not completely numerical. Please try again.");
return EXIT_FAILURE;
}
getDates(dates, &numOfLines, numOfEntries);
sendAllDates(dates, numOfLines);
return EXIT_SUCCESS;
}
void getDates(char dates[MAXLINES][MAXCHARS], int *numOfLines, int numOfEntries)
{
char strDate[MAXCHARS];
int allEntries = FALSE;
if(numOfEntries == 0)
{
allEntries = TRUE;
}
while(fgets(strDate, MAXCHARS, stdin) != NULL)
{
if(numOfEntries > 0 || allEntries)
{
if(checkDate(strDate))
{
fputs(strDate, stdout);
numOfEntries--;
}
}
strcpy(dates[*numOfLines], strDate);
(*numOfLines)++;
}
}
int checkDate(char strDate[])
{
int month = 0, days = 0, year = 0;
const char *DATEPTR = strDate;
if(strDate[0] == '-')
{
DATEPTR++;
}
DATEPTR = parseDate(DATEPTR, &month, DELIMITER);
DATEPTR = parseDate(DATEPTR, &days, DELIMITER);
DATEPTR = parseDate(DATEPTR, &year, NULL);
if(DATEPTR && *DATEPTR == '\0')
{
if(isValidDate(month, days, year))
{
return TRUE;
}
}
return FALSE;
}
const char *parseDate(const char *DATEPTR, int *dateNumber, const char *DATEDELIMITER)
{
if(DATEPTR)
{
char *endPtr = NULL;
long temp = 0;
errno = 0;
temp = strtol(DATEPTR, &endPtr, BASE);
if(errno == ERANGE)
{
return NULL;
}
else if(temp > INT_MAX || temp < INT_MIN )
{
return NULL;
}
else if(endPtr == DATEPTR)
{
return NULL;
}
*dateNumber = (int)temp;
while(isspace((unsigned char)*endPtr))
{
endPtr++;
}
if(DATEDELIMITER)
{
if(*endPtr != *DATEDELIMITER)
{
return NULL;
}
endPtr++;
}
return endPtr;
}
return NULL;
}
int isValidDate(int month, int days, int year)
{
if((month < JAN || month > DEC) || (days < 1 || days > THIRTYONE))
{
return FALSE;
}
if(month == FEB)
{
if(isLeapYear(year))
{
if(days > TWENTYNINE)
{
return FALSE;
}
}
else
{
if(days > TWENTYEIGHT)
{
return FALSE;
}
}
}
else if(month == APR || month == JUN || month == SEP || month == NOV)
{
if(days > THIRTY)
{
return FALSE;
}
}
else
{
if(days > THIRTYONE)
{
return FALSE;
}
}
return TRUE;
}
int isLeapYear(int year)
{
return (year % FOURHUNDRED == 0) || (year % FOUR == 0 && year % ONEHUNDRED != 0);
}
int getNumOfEntries(char *numOfEntries)
{
char *endPtr = NULL;
long temp = 0;
errno = 0;
temp = strtol(numOfEntries, &endPtr, BASE);
if(errno == ERANGE)
{
return NOTVALIDENTRY;
}
else if(temp > INT_MAX || temp < INT_MIN )
{
return NOTVALIDENTRY;
}
else if(endPtr == numOfEntries || *endPtr != '\0')
{
return NOTVALIDENTRY;
}
return (int)temp;
}
void sendAllDates(char dates[MAXLINES][MAXCHARS], int numOfLines)
{
int index;
for(index = 0; index < numOfLines; index++)
{
fputs(dates[index], stdout);
}
}
DateConverter.c
Code:
#include <stdio.h>
#include <stdlib.h>
#define MAXCHARS 80
const char *ABBREVMONTH[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
void convertDateFormat(char []);
void appendDatesToFile(char []);
int main(void)
{
char strDate[MAXCHARS];
convertDateFormat(strDate);
appendDatesToFile(strDate);
return EXIT_SUCCESS;
}
void convertDateFormat(char strDate[])
{
const char *STRMONTH = NULL;
int month = 0, days = 0, year = 0;
fputs("List Of all valid dates found.\n\n", stdout);
while(fgets(strDate, MAXCHARS, stdin) != NULL)
{
sscanf(strDate, "%d /%d /%d ", &month, &days, &year);
STRMONTH = ABBREVMONTH[month - 1];
fprintf(stdout, "%d %s %d\n", days, STRMONTH, year);
}
}
void appendDatesToFile(char strDate[])
{
fputs("List of all dates in the input file.\n\n", stdout);
while(fgets(strDate, MAXCHARS, stdin) != NULL)
{
fputs(strDate, stdout);
}
}
Separate they work fine, but when combined, causes a seg fault(core dump). My professor said that I need to send some kind signal to the second program(DateConverter.c) to tell it to stop reading. I figured that since I'm using fgets to read in the dates, then once I'm done sending all the files from the first program to the second, I can then pipe EOF to the second program to tell it stop reading. My assumption for why this is not working is that before program 2 can finish appending the dates to the file, program 1 might already be sending an EOF to program 2 and causes it to prematurely. What do you guys think?