Code:
/************************************************************/
// Preprocessor Directives
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SUCCESSFUL 1 // Return value
#define FAILED 0 // Return value
#define MAX_STR_SIZE 256 // Max string/filename size
#define MIN_FORMAT 8 // Max minimum format fields
#define MAX_ARTISTS 100 // Max artists allowed in data file
#define FIELDS_COMPLETE 2 // Return value for successful consecutive
#define THREE_FIELDS 3 // Return value for 3 fields successfully read
/************************************************************/
// Global Declarations
typedef struct
{
char *cpFormat;
char *cpDate;
char *cpLabel;
float fCost;
} LABEL; // Artist label-related info
typedef struct
{
char *cpFirstName;
char *cpLastName;
LABEL laLabel;
char *cpImageFile;
char *cpBio; // Artist info
} ARTIST;
char gcFileName[MAX_STR_SIZE] = {' '}; // Stores file name
int giArtistQty = 0; // Artist quantity in data file
/************************************************************/
// Prototype Declarations
int getFile();
void processFile(ARTIST *);
void renderHTML(ARTIST *);
/************************************************************/
// Main Function
void main(){
// Local Declarations
ARTIST *arList = NULL;
// Statements
if(getFile() == SUCCESSFUL){
arList = (ARTIST *)malloc(sizeof(ARTIST)*giArtistQty);
processFile(arList);
renderHTML(arList);
}// if
}
/************************************************************/
// Function Definitions
/*----------------------------------------
Name : getFile
Comments: Validates the format of the file
Return : integer
----------------------------------------*/
int getFile(){
// Local Declarations
//char cRead = ' '; // Stores char for reading
char cCheck = ' '; // Stores char for checking
int c = 0; // Counter
FILE *fpDataFile = NULL; // FILE structure
int iDataRead = 0; // Counter
char *cpTemp = NULL; // Temp string storage
char cTemp = ' ';
float fTemp = 0;
// Statements
printf("\nEnter the path and file name and press <ENTER> : ");
scanf("%s", gcFileName);
fpDataFile = fopen(gcFileName, "r");
if(fpDataFile == NULL){
printf("\n\n\aERROR: File does not exist.");
return FAILED;
}
cpTemp = (char *)malloc(sizeof(char)*MAX_STR_SIZE);
do{
iDataRead = fscanf(fpDataFile,"%s %s %s %s", cpTemp,cpTemp,cpTemp,cpTemp);
if(iDataRead == EOF && c == 0){
printf("\n\n\aERROR: File is empty.");
return FAILED;
}
iDataRead = fscanf(fpDataFile,"%s %c %f", cpTemp,cTemp,fTemp);
if(iDataRead != THREE_FIELDS && iDataRead != EOF){
do{
iDataRead = fscanf(fpDataFile,"%s %c %f", cpTemp,cTemp,fTemp);
} while(iDataRead != THREE_FIELDS && iDataRead != EOF && cTemp != '\n');
if(cTemp == '\n'){
printf("\n\n\aERROR: File contents improperly formatted.");
return FAILED;
}
}
if(iDataRead != EOF){
do{
cCheck = cTemp;
iDataRead = fscanf(fpDataFile, "%s%c", cpTemp, cTemp);
}while(cTemp != '\n' && iDataRead != EOF);
c++;
if(c >= MAX_ARTISTS){
printf("\n\n\aERROR: File cannot contain data for more than %d artists.", MAX_ARTISTS);
return FAILED;
}// if
}// if
} while(iDataRead != EOF);
giArtistQty = (cCheck == '\n')?(c-1):c;
fclose(fpDataFile);
free(cpTemp);
return SUCCESSFUL;
}
/*----------------------------------------
Name : processFile
Comments: Stores data from file into structure
Return : void
----------------------------------------*/
void processFile(ARTIST *arList){
// Local Declarations
char *cpTemp1 = NULL; // Temp string storage
char *cpTemp2 = NULL; // Temp string storage
FILE *fpDataFile = NULL; // FILE pointer
int a = 0; // Counter
char cChar = ' '; // Temp character storage
// Statements
cpTemp1 = (char *)malloc(sizeof(char)*MAX_STR_SIZE);
cpTemp2 = (char *)malloc(sizeof(char)*MAX_STR_SIZE);
fpDataFile = fopen(gcFileName, "r");
for(a=0;a<giArtistQty;a++){
fscanf(fpDataFile, "%s", cpTemp1);
(arList+a)->cpFirstName = (char
*)malloc(sizeof(char)*((strlen(cpTemp1))+1));
*( (arList+a)->cpFirstName ) = '\0';
strcat( (arList+a)->cpFirstName, cpTemp1);
fscanf(fpDataFile, "%s", cpTemp1);
(arList+a)->cpLastName = (char
*)malloc(sizeof(char)*((strlen(cpTemp1))+1));
*( (arList+a)->cpLastName ) = '\0';
if(*cpTemp1 != '?'){
strcat( (arList+a)->cpLastName, cpTemp1 );
}
fscanf(fpDataFile, "%s", cpTemp1);
(arList+a)->laLabel.cpFormat = (char
*)malloc(sizeof(char)*((strlen(cpTemp1))+1));
*( (arList+a)->laLabel.cpFormat ) = '\0';
strcat( (arList+a)->laLabel.cpFormat, cpTemp1);
fscanf(fpDataFile, "%s", cpTemp1);
(arList+a)->laLabel.cpDate = (char
*)malloc(sizeof(char)*((strlen(cpTemp1))+1));
*( (arList+a)->laLabel.cpDate ) = '\0';
strcat( (arList+a)->laLabel.cpDate, cpTemp1);
*cpTemp2 = '\0';
if(fscanf(fpDataFile, "%s %f", cpTemp1, &((arList+a)->laLabel.fCost))
!= FIELDS_COMPLETE){
do{
strcat(cpTemp2, cpTemp1);
strcat(cpTemp2, " ");
}while(fscanf(fpDataFile, "%s %f", cpTemp1,
&((arList+a)->laLabel.fCost)) != FIELDS_COMPLETE);
}// if
strcat(cpTemp2, cpTemp1);
(arList+a)->laLabel.cpLabel = (char
*)malloc(sizeof(char)*((strlen(cpTemp2))+1));
*( (arList+a)->laLabel.cpLabel ) = '\0';
strcat( (arList+a)->laLabel.cpLabel, cpTemp2 );
fscanf(fpDataFile, "%s", cpTemp1);
(arList+a)->cpImageFile = (char
*)malloc(sizeof(char)*((strlen(cpTemp1))+1));
*( (arList+a)->cpImageFile ) = '\0';
strcat( (arList+a)->cpImageFile, cpTemp1 );
*cpTemp2 = '\0';
if(fscanf(fpDataFile, "%s%c", cpTemp1, &cChar) == FIELDS_COMPLETE &&
cChar != '\n'){
do{
strcat(cpTemp2, cpTemp1);
strcat(cpTemp2, " ");
}while(fscanf(fpDataFile, "%s%c", cpTemp1, &cChar) != EOF && cChar
!= '\n');
}
strcat(cpTemp2, cpTemp1);
(arList+a)->cpBio = (char
*)malloc(sizeof(char)*((strlen(cpTemp2))+1));
*((arList+a)->cpBio) = '\0';
strcat( (arList+a)->cpBio, cpTemp2 );
}// for
fclose(fpDataFile);
free(cpTemp2);
free(cpTemp1);
}
/*----------------------------------------
Name : renderHTML
Comments: Creates HTML pages from artist data
Return : void
----------------------------------------*/
void renderHTML(ARTIST *arList){
// Local Declarations
int a = 0; // Counter
FILE *fpHTML = NULL; // FILE pointer
FILE *fpIndex = NULL; // FILE pointer
char *cpFileName = NULL; // HTML file name
// Statements
cpFileName = (char *)malloc(sizeof(char)*MAX_STR_SIZE);
fpIndex = fopen("index.html", "w");
fprintf(fpIndex,"<html>\n<head>\n<title>Music Artists</title>\n</head>\n<body>\n");
fprintf(fpIndex,"<h1 align=\"center\"><u>Music Artists</u></h1>\n");
fprintf(fpIndex,"<p align=\"left\">Make your selection from the list below:</p>\n<ul>\n");
for(a = 0;a < giArtistQty;a++){
*cpFileName = '\0';
strcat(cpFileName, (arList+a)->cpFirstName);
strcat(cpFileName, "_");
strcat(cpFileName, (arList+a)->cpLastName);
strcat(cpFileName, ".html");
fpHTML = fopen(cpFileName, "w");
fprintf(fpHTML,"<html>\n<head>\n<title>%s %s</title>\n</head>\n<body>\n",(arList+a)->cpFirstName,(arList+a)->cpLastName);
fprintf(fpHTML,"<img SRC=\"%s\" BORDER=0 height=170 width=170>\n",(arList+a)->cpImageFile);
free((arList+a)->cpImageFile);
fprintf(fpHTML,"<br><b>Name</b>: %s %s\n",(arList+a)->cpFirstName,(arList+a)->cpLastName);
fprintf(fpHTML,"<br><b>Format</b>: %s\n",
(arList+a)->laLabel.cpFormat);
free((arList+a)->laLabel.cpFormat);
fprintf(fpHTML,"<br><b>Release Date</b>: %s\n",(arList+a)->laLabel.cpDate);
free((arList+a)->laLabel.cpDate);
fprintf(fpHTML,"<br><b>Label</b>: %s\n",(arList+a)->laLabel.cpLabel);
free((arList+a)->laLabel.cpLabel);
fprintf(fpHTML,"<br><b>Cost</b>: $%.2f\n",(arList+a)->laLabel.fCost);
fprintf(fpHTML,"<br><b>Biography</b>: %s\n<br> \n</body>\n</html>",(arList+a)->cpBio);
free((arList+a)->cpBio);
fclose(fpHTML);
fprintf(fpIndex," <li>\n <p align=\"left\"><a href=\"%s\">%s %s</a></li>\n",cpFileName,(arList+a)->cpFirstName,(arList+a)->cpLastName);
free((arList+a)->cpFirstName);
free((arList+a)->cpLastName);
}
free(arList);
fprintf(fpIndex,"</ul>\n<br> \n</body>\n</html>");
fclose(fpIndex);
free(cpFileName);
}