#pragma hdrstop #include #include #include #include #include #define MAX_CARS 1000 #define MAX_CHASSIS 200 #define MAX_ENGINES 100 #define MAX_TRANNIES 100 #define MAX_TURBOS 50 #define MAX_SOURCES 50 #define PI 3.14159 // Version Notes: // 2011.12.08 - switched to data input via csv files (tabbed delimited). // Create a generic structure to hold the car database struct car { char name[20]; char family[30]; char year[20]; char engine[20]; char turbo[20]; char chassis[3][20]; char tranny[3][20]; float diff_ratio[3]; char notes[1000]; float rpm; } volvo[MAX_CARS]; // Create a generic structure to hold chassis database struct chassis { char name[40]; char family[40]; int num_doors; //2=coupe, 3=2dr hatch, 4=sedan, 5=wagon/4dr hatch float wheelbase; //inches float length; float width; float height; float curb_wt; //lb float turn_radius; //ft char front_suspension[80]; char rear_suspension[80]; float diff_ratio; char notes[1000]; } vchassis[MAX_CHASSIS]; // Create a generic structure to hold transmission database struct tranny { char name[40]; char type[40]; char maker[40]; int num_gears; float ratios[7]; char notes[1000]; } vtranny[MAX_TRANNIES]; // Create a generic structure to hold engine database struct engine { char name[40]; int num_cylinders; int num_valves; //valves per cylinder float displacement; //litres float compression; char fuel_type[40]; //gas, diesel, propane .... char fuel_delivery[200]; //SU carb, LHxxx electronic ... char turbo[40]; // not available, brand name, or yes char notes[1000]; } vengine[MAX_ENGINES]; // Create a generic structure to hold turbo database struct turbo { char name[40]; char notes[1000]; } vturbo[MAX_TURBOS]; // Create a generic structure to hold info source database struct source { char id[40]; char notes[1000]; } vsource[MAX_SOURCES]; int read_chassis_csv(); int read_engine_csv(); int read_source_csv(); int read_tranny_csv(); int read_turbo_csv(); int read_car_csv(); void getfields(int num_fields); void check_chassis (int i, int num_chassis); void check_engine (int i, int num_engines); void check_turbo (int i, int num_turbos); void check_tranny (int i, int num_tranny); void check_source (char *notes, int num_sources); int insert_hyperlink (char *notes); /* Not yet used float calc_rpm (float final_tranny_ratio, float final_diff_ratio, float rim_dia, float aspect_ratio, float tire_width); */ int create_carpage (int num_cars, char *output_filename, char *family); int create_chassispage (int num_chassis, int num_cars); int create_trannypage (int num_tranny, int num_cars); int create_enginepage (int num_engines, int num_cars); int create_turbopage (int num_turbos, int num_cars); int create_sourcepage (int num_sources, int num_cars, int num_chassis, int num_engines, int num_turbos, int num_tranny); int fprint_footer (FILE *fp); int fprint_header (FILE *fp, char *title); void error_msg(char *msg); char buf[1000], field[20][1000]; #pragma argsused int main(int argc, char* argv[]) { int num_chassis, num_tranny, num_cars, num_engines, num_turbos, num_sources; // Note that in the following, data stored in location i, starting from 0. // The object counter is incremented to record the # of object stored. // Note that because of the 0 index start, the number of objects is one more // than the index. //Build the source info num_sources = read_source_csv(); // Build the chassis num_chassis = read_chassis_csv(); // Build the transmissions num_tranny = read_tranny_csv(); // Build the engines num_engines = read_engine_csv(); // Build the turbos num_turbos = read_turbo_csv(); //Build the cars num_cars = read_car_csv(); // Create the web pages create_chassispage(num_chassis, num_cars); create_enginepage(num_engines, num_cars); create_trannypage(num_tranny, num_cars); create_turbopage (num_turbos, num_cars); create_sourcepage (num_sources, num_cars, num_chassis, num_engines, num_turbos, num_tranny); create_carpage(num_cars, "cars.htm", "Volvo"); create_carpage(num_cars, "Earlycars.htm", "Early series"); create_carpage(num_cars, "PVcars.htm", "PV series"); create_carpage(num_cars, "P1800cars.htm", "P1800 series"); create_carpage(num_cars, "120cars.htm", "120 series"); create_carpage(num_cars, "140cars.htm", "140/160 series"); create_carpage(num_cars, "240cars.htm", "240/260 series"); create_carpage(num_cars, "300cars.htm", "300 series"); create_carpage(num_cars, "400cars.htm", "400 series"); create_carpage(num_cars, "700cars.htm", "700/900 series"); create_carpage(num_cars, "850cars.htm", "850/S70/V70 series"); create_carpage(num_cars, "S40cars.htm", "S40/V40 series"); create_carpage(num_cars, "S80cars.htm", "S80 series"); create_carpage(num_cars, "SUVcars.htm", "SUV series"); getch(); return 0; } void check_chassis (int i, int num_chassis) { int j, match; match=0; for (j=0; j0 && strstr(notes, vsource[j].id)) match = 1; } if (match ==0) error_msg("Reference to unknown source."); } return; } int insert_hyperlink (char *notes) { char buf[2000], ref[50]; int len_ref, len_buf, len_notes, i, k=0, r=0; // , r_left, r_right //ensure that the buffer is terminated. Had some trouble with strcat not adding final \0 for (i=0;i<1000;i++)buf[i]='\0'; len_notes=strlen(notes); for (i=0; i"); //Then the link text (the reference itself) strcat (buf, ref); //Finally, close off the anchor strcat(buf, ""); len_buf=strlen(buf); k=len_buf; //put the indices just beyond the end of the added text i=i+len_ref-1; //skip over the ref text since it has been added in already //Now ready to continue } } //All done building the new text. Copy over old text if not too long. len_buf=strlen(buf); if (strlen(buf)>=1000) error_msg ("Length of note exceeds limit"); strcpy (notes, buf); len_buf=strlen(buf); //don't really need this but what the heck. return (len_buf); } void check_tranny (int i, int num_tranny) { int j, match; match=0; for (j=0; j=MAX_CARS) error_msg ("Can't build car - number limit reached"); fgets (buf, 80, fp); //read rest of line and ignore // read header line and ignore fgets (buf, 1000, fp); // read the records for (i=0;i=MAX_CHASSIS) error_msg ("Can't build chassis - number limit reached"); fgets (buf, 80, fp); //read rest of line and ignore // read header line and ignore fgets (buf, 1000, fp); // read the records for (i=0;i=MAX_TRANNIES) error_msg ("Can't build tranny - number limit reached"); fgets (buf, 80, fp); //read rest of line and ignore // read header line and ignore fgets (buf, 1000, fp); // read the records for (i=0;i=MAX_ENGINES) error_msg ("Can't build engine - number limit reached"); fgets (buf, 80, fp); //read rest of line and ignore // read header line and ignore fgets (buf, 1000, fp); // read the records for (i=0;i=MAX_TURBOS) error_msg ("Can't build turbo - number limit reached"); fgets (buf, 80, fp); //read rest of line and ignore // read header line and ignore fgets (buf, 1000, fp); // read the records for (i=0;i=MAX_SOURCES) error_msg ("Can't build sources - number limit reached"); fgets (buf, 80, fp); //read rest of line and ignore // read header line and ignore fgets (buf, 1000, fp); // read the records for (i=0;iTable of Contents
\n"); last = 0; tally = 0; for (i=0;i0 && (strcmp(volvo[i].year, volvo[last].year) || i==0)) {//****careful, the above logic doesn't reliably print the first year in the TOC***** //****Should change char year to into year before fixing. fprintf(fp, "%s ", volvo[i].year, volvo[i].year); last = i; } } fprintf(fp, "\n
This page contains %d cars
    \n", tally); //reset the 'last printed' marker for first car to be printed for (i=num_cars-1;i>=0;i--) if (go[i]>0)last = i; for (i=0;i0) { if (i>0 && strcmp(volvo[i].year, volvo[last].year)) { fprintf(fp, "
    \n", volvo[i].year); last = i; } fprintf(fp, "
    ", volvo[i].year, volvo[i].name); fprintf(fp, "
  • %s %s\n", volvo[i].year, volvo[i].name); fprintf(fp, "
      \n"); fprintf(fp, "
    • Chassis: %s", volvo[i].chassis[0], volvo[i].chassis[0]); fprintf(fp, " %s", volvo[i].chassis[1], volvo[i].chassis[1]); fprintf(fp, " %s, ", volvo[i].chassis[2], volvo[i].chassis[2]); fprintf(fp, "Engine: %s ", volvo[i].engine, volvo[i].engine); fprintf(fp, "%s\n", volvo[i].turbo, volvo[i].turbo); fprintf(fp, "
    • Transmission / final drive ratio: "); if (strcmp(volvo[i].tranny[0], "")) fprintf(fp, "%s / %4.2f:1", volvo[i].tranny[0], volvo[i].tranny[0], volvo[i].diff_ratio[0]); if (strcmp(volvo[i].tranny[1], "")) fprintf(fp, " %s / %4.2f:1", volvo[i].tranny[1], volvo[i].tranny[1], volvo[i].diff_ratio[1]); if (strcmp(volvo[i].tranny[2], "")) fprintf(fp, " %s / %4.2f:1\n", volvo[i].tranny[2], volvo[i].tranny[2], volvo[i].diff_ratio[2]); fprintf(fp, "
    • Notes: %s\n", volvo[i].notes); fprintf(fp, "
    \n"); } } fprint_footer(fp); fclose (fp); return 0; } int create_trannypage (int num_tranny, int num_cars) { int i, j, assigned[MAX_CARS]; FILE *fp; char output_filename[13]="tranny.htm"; if (( fp = fopen(output_filename,"w")) == NULL) { printf("Could not open %s",output_filename); return(0); } fprint_header(fp, "Volvo Transmission Page"); // Print hyperlinks to the various trannies as a table of contents fprintf(fp, "Table of Contents
    \n"); for (i=0;i%s ", vtranny[i].name, vtranny[i].name); } fprintf(fp, "\n
    Current database contains %d transmissions
      \n", num_tranny); //initialize flag for (j=0;j", vtranny[i].name); fprintf(fp, "
    • Transmission name: %s\n", vtranny[i].name); fprintf(fp, "
        \n"); fprintf(fp, "
      • Type: %d speed %s\n", vtranny[i].num_gears, vtranny[i].type); fprintf(fp, "
      • Manufacturer: %s\n", vtranny[i].maker); fprintf(fp, "
      • Gear ratios: "); for (j=0; j(%d)%5.2f:1 ", j+1, vtranny[i].ratios[j]); fprintf(fp, "\n
      • Notes: %s\n", vtranny[i].notes); fprintf(fp, "
      • Cars that use this transmission:"); for (j=0;j%s %s)", volvo[j].year, volvo[j].name, volvo[j].year, volvo[j].name); assigned[j]=1; } } fprintf(fp, "
      \n"); } fprintf(fp, "
    • Cars with no transmission assigned:\n"); for (j=0;j%s %s)", volvo[j].year, volvo[j].name, volvo[j].year, volvo[j].name); } fprint_footer(fp); fclose (fp); return 0; } int create_chassispage (int num_chassis, int num_cars) { int i, j, assigned[MAX_CARS]; FILE *fp; char output_filename[13]="chassis.htm"; if (( fp = fopen(output_filename,"w")) == NULL) { printf("Could not open %s",output_filename); return(0); } fprint_header(fp, "Volvo Chassis Page"); // Print hyperlinks to the various chassis as a table of contents fprintf(fp, "Table of Contents
      \n"); fprintf(fp, "
        \n
      • %s: ", vchassis[0].family); fprintf(fp, "%s ", vchassis[0].name, vchassis[0].name); for (i=1;i%s: ", vchassis[i].family); } fprintf(fp, "%s ", vchassis[i].name, vchassis[i].name); } fprintf(fp, "\n
      \nCurrent database contains %d chassis
        \n", num_chassis); //initialize flag for (j=0;j", vchassis[i].name); fprintf(fp, "
      • Chassis name: %s, %d door. Member of the %s.\n", vchassis[i].name, vchassis[i].num_doors, vchassis[i].family); fprintf(fp, "
          \n"); fprintf(fp, "
        • Front suspension: %s, Rear suspension: %s\n", vchassis[i].front_suspension, vchassis[i].rear_suspension); fprintf(fp, "
        • Wheelbase = %5.1f inches = %5.1f cm.\n", vchassis[i].wheelbase, vchassis[i].wheelbase*2.54); fprintf(fp, "
        • Length = %5.1f inches = %5.1f cm.\n", vchassis[i].length, vchassis[i].length*2.54); fprintf(fp, "
        • Width = %5.1f inches = %5.1f cm.\n", vchassis[i].width, vchassis[i].width*2.54); fprintf(fp, "
        • Height = %5.1f inches = %5.1f cm.\n", vchassis[i].height, vchassis[i].height*2.54); fprintf(fp, "
        • Curb Weight = %5.1f lbs. = %5.1f kg.\n", vchassis[i].curb_wt, vchassis[i].curb_wt/2.204622622); fprintf(fp, "
        • Turning radius = %5.1f ft. = %5.1f m.\n", vchassis[i].turn_radius, vchassis[i].turn_radius*0.3048); // fprintf(fp, "
        • Final drive ratio = %5.2f:1\n", // vchassis[i].diff_ratio); fprintf(fp, "
        • Notes: %s\n", vchassis[i].notes); fprintf(fp, "
        • Cars that use this chassis:"); for (j=0;j%s %s)", volvo[j].year, volvo[j].name, volvo[j].year, volvo[j].name); strcpy(volvo[j].family, vchassis[i].family);//associate car with a family for later use assigned[j]=1; } } fprintf(fp, "
        \n"); } fprintf(fp, "
      • Cars with no chassis assigned:\n"); for (j=0;j%s %s)", volvo[j].year, volvo[j].name, volvo[j].year, volvo[j].name); } fprint_footer(fp); fclose (fp); return 0; } int create_enginepage (int num_engines, int num_cars) { int i, j, assigned[MAX_CARS]; FILE *fp; char output_filename[13]="engines.htm"; if (( fp = fopen(output_filename,"w")) == NULL) { printf("Could not open %s",output_filename); return(0); } fprint_header(fp, "Volvo Engine Page"); // Print hyperlinks to the various engines as a table of contents fprintf(fp, "Table of Contents
        \n"); for (i=0;i%s ", vengine[i].name, vengine[i].name); } fprintf(fp, "\n
        Current database contains %d engines
          \n", num_engines); //initialize flag for (j=0;j", vengine[i].name); fprintf(fp, "
        • Engine name: %s\n", vengine[i].name); fprintf(fp, "
            \n"); fprintf(fp, "
          • %d cylinders, ", vengine[i].num_cylinders); fprintf(fp, "%d valves / cylinder\n", vengine[i].num_valves); fprintf(fp, "
          • Turbo: %s\n", vengine[i].turbo); fprintf(fp, "
          • Fuel type: %s, Fuel delivery: %s\n", vengine[i].fuel_type, vengine[i].fuel_delivery); fprintf(fp, "
          • Displacement: %5.3f litres = %5.1f cu. in.\n", vengine[i].displacement, vengine[i].displacement*61.0237440947); fprintf(fp, "
          • Compression ratio: %4.1f : 1\n", vengine[i].compression); fprintf(fp, "
          • Notes: %s\n", vengine[i].notes); fprintf(fp, "
          • Cars that use this engine:"); for (j=0;j%s %s)", volvo[j].year, volvo[j].name, volvo[j].year, volvo[j].name); assigned[j]=1; } } fprintf(fp, "\n"); fprintf(fp, "
          \n"); } fprintf(fp, "
        • Cars with no engine assigned:\n"); for (j=0;j%s %s)", volvo[j].year, volvo[j].name, volvo[j].year, volvo[j].name); } fprint_footer(fp); fclose (fp); return 0; } int create_turbopage (int num_turbos, int num_cars) { int i, j; FILE *fp; char output_filename[13]="turbos.htm"; if (( fp = fopen(output_filename,"w")) == NULL) { printf("Could not open %s",output_filename); return(0); } fprint_header(fp, "Volvo Turbo Page"); // Print hyperlinks to the various trannies as a table of contents fprintf(fp, "Table of Contents
          \n"); for (i=0;i%s ", vturbo[i].name, vturbo[i].name); } fprintf(fp, "\n
          Current database contains %d turbos
            \n", num_turbos); for (i=0;i", vturbo[i].name); fprintf(fp, "
          • Turbo name: %s\n", vturbo[i].name); fprintf(fp, "
              \n"); fprintf(fp, "
            • Notes: %s\n", vturbo[i].notes); fprintf(fp, "
            • Cars that use this turbo:"); for (j=0;j%s %s)", volvo[j].year, volvo[j].name, volvo[j].year, volvo[j].name); } fprintf(fp, "
            \n"); } fprint_footer(fp); fclose (fp); return 0; } int create_sourcepage (int num_sources, int num_cars, int num_chassis, int num_engines, int num_turbos, int num_tranny) { int i, j; FILE *fp; char output_filename[13]="sources.htm"; if (( fp = fopen(output_filename,"w")) == NULL) { printf("Could not open %s",output_filename); return(0); } fprint_header(fp, "Volvo Source Page"); // Print hyperlinks to the various sources as a table of contents fprintf(fp, "Table of Contents
            \n"); for (i=0;i%s ", vsource[i].id, vsource[i].id); } fprintf(fp, "\n
            Current database contains %d sources
              \n", num_sources); for (i=0;i", vsource[i].id); fprintf(fp, "
            • %s %s\n", vsource[i].id, vsource[i].notes); fprintf(fp, "
                \n"); fprintf(fp, "
              • Car datasets that use this source:"); for (j=0;j%s %s)", volvo[j].year, volvo[j].name, volvo[j].year, volvo[j].name); } fprintf(fp, "
              • Chassis datasets that use this source:"); for (j=0;j%s)", vchassis[j].name, vchassis[j].name); } fprintf(fp, "
              • Engine datasets that use this source:"); for (j=0;j%s)", vengine[j].name, vengine[j].name); } fprintf(fp, "
              • Turbo datasets that use this source:"); for (j=0;j%s)", vturbo[j].name, vturbo[j].name); } fprintf(fp, "
              • Transmission datasets that use this source:"); for (j=0;j%s)", vtranny[j].name, vtranny[j].name); } fprintf(fp, "
              \n"); } fprint_footer(fp); fclose (fp); return 0; } int fprint_header (FILE *fp, char *title) { fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "%s\n", title); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n" "\n" " \n" " \n" " \n" " \n"); fprintf(fp, "
              \n" " \n" " \n" "
              Volvo\n" " Information
              \n" " \n" " \n" " , HOME (url: www.nuceng.ca/bill/)
              \n" "
              \n" "
              \n" "
              \n"); fprintf(fp, "Components: Chassis " "Engines " "Turbos " "Transmissions
              \n"); fprintf(fp, "Models: All models " "Early series " "PV series " "120 series " "P1800 series " "140/160 series " "240/260 series " "300 series " "400 series " "700/900 series " "850/S70/V70 series " "S40/V40 series " "S80 series " "SUV series
              \n"); fprintf(fp, "Information: Sources
              \n"); fprintf(fp, "

              %s

              \n", title); return 0; } int fprint_footer (FILE *fp) { fprintf(fp, "\n"); fprintf(fp,"This page auto-generated by cars.cpp
              "); fprintf(fp, "
              \n"); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); return 0; } void error_msg(char *msg) { printf("ERROR: %s. Program stopped", msg); getch(); exit(1); } void getfields(int num_fields) { //globals assumed: char buf, field[k][r] int i, r, k; i=0; r=0; for (k=0; k < num_fields; k++) //loop on fields { //Proceed unless a tab field separator or eol or new line found //copy the keyword characters while ((buf[r]!='\t') && (buf[r]!='\0') && (buf[r]!='\n')) { field[k][r-i] = buf[r]; r++; } field[k][r-i] = '\0'; r++; i=r; } //} return; }