Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ourhdr.h"
typedef struct // Country Data struct declaration
{
char code[4]; // Country Code
char name[50]; // Country Name
float life_expectancy; // Life Expentancy of the Country's citizen
int pop; // Country's Population
} DATATYPE;
typedef struct // Index Data struct declaration
{
char code[4];
long int offset; // offset of the data
} INDEX;
INDEX StructArray[300]; // for a lot of them
DATATYPE ActualStruct; // for a single struct
DATATYPE DatabaseArray[300]; // DATATYPE array
/***********************Index Copy function************************************************/
void indexCopy(INDEX* dest, INDEX src)
{
strcpy(dest->code, src.code);
dest->offset = src.offset;
}
/*************************Insertion Sort function******************************************/
void sort(INDEX SortArray[], int n)
{
int j;
for(j=0; j < n;j++)
{
int k;
INDEX temp; //Create a blank index data object
indexCopy(&temp, SortArray[j]); //copy the data from the current line
k = j-1;
while (strcmp(SortArray[k].code, temp.code) >= 0 && k>=0)
{
indexCopy(&SortArray[k+1], SortArray[k]); //Now move them over
k = k - 1;
}
indexCopy(&SortArray[k+1], temp);//And move the temp one back in
}
}
/*************************Print Sorted Array**********************************************/
void printsort(int size)
{
DATATYPE country;
sort(StructArray,size); // call sort function
FILE *FI;
if((FI = fopen("DATABASE.txt", "r")) == NULL) // open DATABASE for read
err_sys("Open DATABASE Fail\n");
int i;
printf("--------------------------------------------------------------------------------------------------------\n");
printf(" CODE \t\t\t COUNTRY NAME \t\t\t POPULATION LIFE EXPECTANCY \t OFFSET\n");
printf("--------------------------------------------------------------------------------------------------------\n");
for (i=0; i<size; i++)
{
fseek(FI,StructArray[i].offset,SEEK_SET); //seek the offset in the binary file
fread(&country, sizeof(DATATYPE),1,FI); // read the struct of array from binary file (4 fields)
printf("%5s%50s%15u%18f%15u\n", country.code, country.name, country.pop, country.life_expectancy, StructArray[i].offset);
}
}
/************************Search Function by Country Code*********************************/
void search(int size)
{
int mid, lower = 0, upper = size, flag = 1;
INDEX cc;
FILE *FI;
if((FI = fopen("DATABASE.txt", "r")) == NULL) // open DATABASE for read
err_sys("Open DATABASE Fail\n");
printf("Enter Country Code to search: ");
scanf("%s", &cc);
for(mid = (lower+upper)/2; lower <= upper; mid = (lower + upper)/2)
{
if(strcmp(StructArray[mid].code, cc.code) == 0) // compare the input with the sorted array
{
printf("The country code is at position %d in the array at offset %u in the binary file.\n", mid, StructArray[mid].offset);
fseek(FI,StructArray[mid].offset,SEEK_CUR); //seek the offset in the binary file
fread(&DatabaseArray[mid], sizeof(DATATYPE),1,FI); // read the struct of array from binary file (4 fields)
printf("%s %s %u %f\n", DatabaseArray[mid].code, DatabaseArray[mid].name, DatabaseArray[mid].pop, DatabaseArray[mid].life_expectancy);
flag = 0;
break;
}
if(strcmp(StructArray[mid].code, cc.code) > 0) // compare the input with the sorted array
upper = mid - 1;
else
lower = mid + 1;
}
if (flag)
printf("Elements not found."); // print this if the input is not in the array
if (fclose(FI)) // close file descriptor FI
err_sys("Close error\n");
}
/****************************Add File***********************************************/
int addFile(DATATYPE* Array2, char* filename, int startHere)
{
int i = startHere;
int size = startHere;
char * Tok; // token from line
FILE *FI, *FO, *FO2;
char Line[1000]; // NO input line (delimited by \n) is longer than 1000
if((FI = fopen(filename, "r")) == NULL) // open a stream from "countries"
err_sys("Open Fail\n");
if((FO = fopen("DATABASE.txt", "a")) == NULL) // open a stream from "countries"
err_sys("Open DATABASE Fail\n");
if((FO2 = fopen("DIRECTORY.txt", "a")) == NULL) // open a stream from "countries"
err_sys("Open DIRECTORY Fail\n");
while ( fgets( (char *) Line,1000,FI) != NULL) // fill buffer up to newline or eof or error
{
Tok = strtok( Line ,",\n"); // skip ID number
Tok = strtok( NULL ,",\n"); // this should get the country code
ActualStruct.code[0] = Tok[0];
ActualStruct.code[1] = Tok[1];
ActualStruct.code[2] = Tok[2];
ActualStruct.code[3] = 0; // To create "string"
Tok = strtok( NULL ,",\n"); // this should get the country name
strncpy(&ActualStruct.name[0],Tok,50); // copy string at most 50 chars
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // this should get the population
ActualStruct.pop = atoi(Tok); // convert string to integer
Tok = strtok( NULL ,",\n"); // this one should get life expectancy
ActualStruct.life_expectancy = atof(Tok); // convert string to a floating point number
strcpy(Array2[i].code,ActualStruct.code); // get the current code
strcpy(Array2[i].name,ActualStruct.name); // get the current name
Array2[i].pop = ActualStruct.pop; // get the current population
Array2[i].life_expectancy = ActualStruct.life_expectancy; // get the current life expectancy
strcpy(StructArray[i].code, ActualStruct.code); // get the current code
StructArray[i].offset = ftell(FO); // get the current offset in the DATABASE file
if (fwrite(&Array2[i], sizeof(DATATYPE),1,FO) != 1) // write the struct to the DATABASE file
err_sys("fwrite error");
i++;
size = i;
}
/****************************Sort the array and write into DIRECTORY*****************************/
sort(StructArray,size); // call sort function
for (i=0; i<size; i++)
{
if (fwrite(&StructArray[i], sizeof(INDEX),1,FO2) != 1) // write the struct to the DIRECTORY file
err_sys("fwrite error");
}
if (fclose(FI)) // close file descriptor FI
err_sys("Close error\n");
if (fclose(FO)) // close file descriptor FO
err_sys("Close error\n");
if (fclose(FO2)) // close file descriptor FO2
err_sys("Close error\n");
}
/****************************************Main Function********************************************/
int main()
{
char userfile[50];
int count = 0;
int size = 0;
count = addFile(DatabaseArray,"AC1.txt",0);
/***********************************read DIRECTORY file into memory******************************/
FILE *infile; // declare an index file pointer
char *buffer;
long numbytes;
if((infile = fopen("DIRECTORY.txt", "rb")) == NULL) // open a stream from "countries"
err_sys("Open DIRECTORY Fail\n");
fseek(infile,0,SEEK_END);
numbytes = ftell(infile); // get the number of bytes
fseek(infile,0, SEEK_SET); // reset the file position indicator to the beginning of the file
buffer = (char*)calloc(numbytes,sizeof(char)); // grab sufficient memory for the buffer
// to hold the text
fread(buffer,sizeof(char),numbytes,infile); // copy all the text into the buffer
fclose(infile);
free(buffer); // free the memory we used for the buffer
/*********************************************MENU************************************************/
int c = -1;
while( c != 4)
{
printf("Please select an option (1 to 4):\n");
printf("1. Add to the DATABASE\n");
printf("2. Search the DATABASE\n");
printf("3. List all the countries in DATABASE by ordered Country Code\n");
printf("4. Press q to exit\n");
fflush(stdin);
c = -1; // error value if scanf fails
scanf("%d", &c);
switch (c)
{
case 1:
printf("Filename(data that you would like to add in): ");
scanf("%s",&userfile);
count = addFile(DatabaseArray, userfile, count);
break;
case 2:
search(size);
break;
case 3:
printsort(size);
break;
case 4:
puts("Exiting program!");
return 0;
default:
printf("\nNot implemented yet!");
}
}
}
Please select an option (1 to 4):
1. Add to the DATABASE
2. Search the DATABASE
3. List all the countries in DATABASE by ordered Country Code
4. Press q to exit
3
--------------------------------------------------------------------------------------------------------
CODE COUNTRY NAME POPULATION LIFE EXPECTANCY OFFSET
--------------------------------------------------------------------------------------------------------
AGO Angola 12878000 38.299999 1408
BDI BWAola 12878000 38.299999 1728
BEN BENeria 31471000 69.699997 1472
BFA BFAola 12878000 38.299999 1664
BWA BWAola 12878000 38.299999 1536
DZA Algeria 31471000 69.699997 0
IOT IOTola 12878000 38.299999 1600
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ourhdr.h"
typedef struct // Country Data struct declaration
{
char code[4]; // Country Code
char name[50]; // Country Name
float life_expectancy; // Life Expentancy of the Country's citizen
int pop; // Country's Population
} DATATYPE;
typedef struct // Index Data struct declaration
{
char code[4];
long int offset; // offset of the data
} INDEX;
INDEX StructArray[300]; // for a lot of them
DATATYPE ActualStruct; // for a single struct
DATATYPE DatabaseArray[300]; // DATATYPE array
/***********************Index Copy function************************************************/
void indexCopy(INDEX* dest, INDEX src)
{
strcpy(dest->code, src.code);
dest->offset = src.offset;
}
/*************************Insertion Sort function******************************************/
void sort(INDEX SortArray[], int n)
{
int j;
for(j=0; j < n;j++)
{
int k;
INDEX temp; //Create a blank index data object
indexCopy(&temp, SortArray[j]); //copy the data from the current line
k = j-1;
while (strcmp(SortArray[k].code, temp.code) >= 0 && k>=0)
{
indexCopy(&SortArray[k+1], SortArray[k]); //Now move them over
k = k - 1;
}
indexCopy(&SortArray[k+1], temp);//And move the temp one back in
}
}
/*************************Print Sorted Array**********************************************/
void printsort(int size)
{
DATATYPE country;
sort(StructArray,size); // call sort function
FILE *FI;
if((FI = fopen("DATABASE.txt", "r")) == NULL) // open DATABASE for read
err_sys("Open DATABASE Fail\n");
int i;
printf("--------------------------------------------------------------------------------------------------------\n");
printf(" CODE \t\t\t COUNTRY NAME \t\t\t POPULATION LIFE EXPECTANCY \t OFFSET\n");
printf("--------------------------------------------------------------------------------------------------------\n");
for (i=0; i<size; i++)
{
fseek(FI,StructArray[i].offset,SEEK_SET); //seek the offset in the binary file
fread(&country, sizeof(DATATYPE),1,FI); // read the struct of array from binary file (4 fields)
printf("%5s%50s%15u%18f%15u\n", country.code, country.name, country.pop, country.life_expectancy, StructArray[i].offset);
}
}
/************************Search Function by Country Code*********************************/
void search(int size)
{
int mid, lower = 0, upper = size, flag = 1;
INDEX cc;
FILE *FI;
if((FI = fopen("DATABASE.txt", "r")) == NULL) // open DATABASE for read
err_sys("Open DATABASE Fail\n");
printf("Enter Country Code to search: ");
scanf("%s", &cc);
for(mid = (lower+upper)/2; lower <= upper; mid = (lower + upper)/2)
{
if(strcmp(StructArray[mid].code, cc.code) == 0) // compare the input with the sorted array
{
printf("The country code is at position %d in the array at offset %u in the binary file.\n", mid, StructArray[mid].offset);
fseek(FI,StructArray[mid].offset,SEEK_CUR); //seek the offset in the binary file
fread(&DatabaseArray[mid], sizeof(DATATYPE),1,FI); // read the struct of array from binary file (4 fields)
printf("%s %s %u %f\n", DatabaseArray[mid].code, DatabaseArray[mid].name, DatabaseArray[mid].pop, DatabaseArray[mid].life_expectancy);
flag = 0;
break;
}
if(strcmp(StructArray[mid].code, cc.code) > 0) // compare the input with the sorted array
upper = mid - 1;
else
lower = mid + 1;
}
if (flag)
printf("Elements not found."); // print this if the input is not in the array
if (fclose(FI)) // close file descriptor FI
err_sys("Close error\n");
}
/***************************Main Function********************************************/
int main(int argc, char *argv[])
{
int i = 0;
int size = 0;
FILE *FI, *FO, *FO2;
char Line[1000]; // NO input line (delimited by \n) is longer than 1000
char * Tok; // token from line
//if (argc!= 2)
// printf("MYAS2 <filename>\n") ;
if((FI = fopen("AC1.txt", "r")) == NULL) // open a stream from "countries"
err_sys("Open Fail\n");
if((FO = fopen("DATABASE.txt", "wb")) == NULL) // open a stream from "countries"
err_sys("Open DATABASE Fail\n");
if((FO2 = fopen("DIRECTORY.txt", "w+")) == NULL) // open a stream from "countries"
err_sys("Open DIRECTORY Fail\n");
while ( fgets( (char *) Line,1000,FI) != NULL) // fill buffer up to newline or eof or error
{
Tok = strtok( Line ,",\n"); // skip ID number
Tok = strtok( NULL ,",\n"); // this should get the country code
ActualStruct.code[0] = Tok[0];
ActualStruct.code[1] = Tok[1];
ActualStruct.code[2] = Tok[2];
ActualStruct.code[3] = 0; // To create "string"
Tok = strtok( NULL ,",\n"); // this should get the country name
strncpy(&ActualStruct.name[0],Tok,50); // copy string at most 50 chars
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // this should get the population
ActualStruct.pop = atoi(Tok); // convert string to integer
Tok = strtok( NULL ,",\n"); // this one should get life expectancy
ActualStruct.life_expectancy = atof(Tok); // convert string to a floating point number
strcpy(DatabaseArray[i].code,ActualStruct.code); // get the current code
strcpy(DatabaseArray[i].name,ActualStruct.name); // get the current name
DatabaseArray[i].pop = ActualStruct.pop; // get the current population
DatabaseArray[i].life_expectancy = ActualStruct.life_expectancy; // get the current life expectancy
strcpy(StructArray[i].code, ActualStruct.code); // get the current code
StructArray[i].offset = ftell(FO); // get the current offset in the DATABASE file
if (fwrite(&DatabaseArray[i], sizeof(DATATYPE),1,FO) != 1) // write the struct to the DATABASE file
err_sys("fwrite error");
i++;
size = i;
}
/****************************Sort the array and write into DIRECTORY*****************************/
sort(StructArray,size); // call sort function
for (i=0; i<size; i++)
{
if (fwrite(&StructArray[i], sizeof(INDEX),1,FO2) != 1) // write the struct to the DIRECTORY file
err_sys("fwrite error");
}
if (fclose(FI)) // close file descriptor FI
err_sys("Close error\n");
if (fclose(FO)) // close file descriptor FO
err_sys("Close error\n");
if (fclose(FO2)) // close file descriptor FO2
err_sys("Close error\n");
/***********************************read DIRECTORY file into memory******************************/
FILE *infile; // declare an index file pointer
char *buffer;
long numbytes;
if((infile = fopen("DIRECTORY.txt", "rb")) == NULL) // open a stream from "countries"
err_sys("Open DIRECTORY Fail\n");
fseek(infile,0,SEEK_END);
numbytes = ftell(infile); // get the number of bytes
fseek(infile,0, SEEK_SET); // reset the file position indicator to the beginning of the file
buffer = (char*)calloc(numbytes,sizeof(char)); // grab sufficient memory for the buffer
// to hold the text
fread(buffer,sizeof(char),numbytes,infile); // copy all the text into the buffer
fclose(infile);
free(buffer); // free the memory we used for the buffer
/*********************************************MENU************************************************/
int c = -1;
while( c != 4)
{
printf("Please select an option (1 to 4):\n");
printf("1. Add to the DATABASE\n");
printf("2. Search the DATABASE\n");
printf("3. List all the countries in DATABASE by ordered Country Code\n");
printf("4. Press q to exit\n");
fflush(stdin);
c = -1; // error value if scanf fails
scanf("%d", &c);
switch (c)
{
case 1:
printf("Filename(data that you would like to add in): ");
break;
case 2:
search(size);
break;
case 3:
printsort(size);
break;
case 4:
puts("Exiting program!");
return 0;
default:
printf("\nNot implemented yet!");
}
}
}
cpfoo@csa02 as2$ gcc sort1.c error.c -o MY -g
cpfoo@csa02 as2$ gdb MY
GNU gdb 6.6
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "sparc-sun-solaris2.8"...
(gdb) b addFile
Breakpoint 1 at 0x1127c: file sort1.c, line 113.
(gdb) r
Starting program: /home/ugrad/cpfoo/CS224/as2/MY
warning: Temporarily disabling breakpoints for unloaded shared library "/usr/lib/ld.so.1"
Breakpoint 1, addFile (Array2=0x224b4, filename=0x11f50 "AC1.txt", startHere=0) at sort1.c:113
113 int i = startHere;
(gdb) p i
$1 = -12627664
(gdb) n
114 int size = startHere;
(gdb) p size
$2 = 0
(gdb) n
119 if((FI = fopen(filename, "r")) == NULL) // open a stream from "countries"
(gdb) p filename
$3 = 0x11f50 "AC1.txt"
(gdb) n
122 if((FO = fopen("DATABASE.txt", "a")) == NULL) // open a stream from "countries"
(gdb) n
125 if((FO2 = fopen("DIRECTORY.txt", "a")) == NULL) // open a stream from "countries"
(gdb) n
128 while ( fgets( (char *) Line,1000,FI) != NULL) // fill buffer up to newline or eof or error
(gdb) p Line
$4 = "?9(\000\000\000\002\000\000\000\000'", '\0' <repeats 20 times>, "???\000\000\000 \000\000\000\000\000\000\000\000\000?@\000\005?4_??4_?\000\000\000\000\000\000\000d", '\0' <repeats 20 times>, "??E\000\000\000\000\000???\000\n?\030\000\000\000\000\000\000\000\000?9\000\000???\020?4\035\004\000\000\000\000", '?' <repeats 128 times>, "\000\000\000\000\000\000\000\000\000\b", '\0' <repeats 194 times>, "?77\000 \000\000\000??I\020\000\000\000\000\000\000\000\004??{d\000\000\000\024\000\000\000\b\000\000\000\000??@???B?\000\002<???B???I\020?4\0348??"...
(gdb) n
131 Tok = strtok( Line ,",\n"); // skip ID number
(gdb) p Line
$5 = "115,DZA,Algeria,Africa,Northern Africa,2381741,1962,31471000,69.7,49982,Al-Jaza?\210\232?\211?ir/Alg?\210\232Ã rie,Republic,Abdelaziz Bouteflika,35,DZ\n\000", '?' <repeats 119 times>, "\000\000\000\000\000\000\000\000\000\b", '\0' <repeats 194 times>, "?77\000 \000\000\000??I\020\000\000\000\000\000\000\000\004??{d\000\000\000\024\000\000\000\b\000"...
(gdb) n
133 Tok = strtok( NULL ,",\n"); // this should get the country code
(gdb) p NULL
No symbol "NULL" in current context.
(gdb) p Tok
$6 = 0xffbff398 "115"
(gdb) n
134 ActualStruct.code[0] = Tok[0];
(gdb) p Tok
$7 = 0xffbff39c "DZA"
(gdb) n
135 ActualStruct.code[1] = Tok[1];
(gdb) n
136 ActualStruct.code[2] = Tok[2];
(gdb) n
137 ActualStruct.code[3] = 0; // To create "string"
(gdb) n
139 Tok = strtok( NULL ,",\n"); // this should get the country name
(gdb) n
140 strncpy(&ActualStruct.name[0],Tok,50); // copy string at most 50 chars
(gdb) p Tok
$8 = 0xffbff3a0 "Algeria"
(gdb) n
142 Tok = strtok( NULL ,",\n"); // skip
(gdb) n
143 Tok = strtok( NULL ,",\n"); // skip
(gdb) n
144 Tok = strtok( NULL ,",\n"); // skip
(gdb) n
145 Tok = strtok( NULL ,",\n"); // skip
(gdb) n
147 Tok = strtok( NULL ,",\n"); // this should get the population
(gdb) n
148 ActualStruct.pop = atoi(Tok); // convert string to integer
(gdb) p Tok
$9 = 0xffbff3cc "31471000"
(gdb) n
150 Tok = strtok( NULL ,",\n"); // this one should get life expectancy
(gdb) n
151 ActualStruct.life_expectancy = atof(Tok); // convert string to a floating point number
(gdb) p Tok
$10 = 0xffbff3d5 "69.7"
(gdb) n
153 strcpy(Array2[i].code,ActualStruct.code); // get the current code
(gdb) p Array2[i].code
$11 = "\000\000\000"
(gdb) p ActualStruct.code
$12 = "DZA"
(gdb) n
154 strcpy(Array2[i].name,ActualStruct.name); // get the current name
(gdb) p Array2[i].name
$13 = '\0' <repeats 49 times>
(gdb) p ActualStruct.name
$14 = "Algeria", '\0' <repeats 42 times>
(gdb) n
155 Array2[i].pop = ActualStruct.pop; // get the current population
(gdb) p Array2[i].pop
$15 = 0
(gdb) p ActualStruct.pop
$16 = 31471000
(gdb) p Array2[0].pop
$17 = 0
(gdb) n
156 Array2[i].life_expectancy = ActualStruct.life_expectancy; // get the current life expectancy
(gdb) p Array2[1].life_expectancy
$18 = 0
(gdb) p ActualStruct.life_expectancy
$19 = 69.6999969
(gdb) n
158 strcpy(StructArray[i].code, ActualStruct.code); // get the current code
(gdb) p StructArray[i].code
$20 = "\000\000\000"
(gdb) p ActualStruct.code
$21 = "DZA"
(gdb) n
159 StructArray[i].offset = ftell(FO); // get the current offset in the DATABASE file
(gdb) p ftell(FO)
$22 = 896
(gdb) p StructArray[i].offset
$23 = 0
(gdb) n
161 if (fwrite(&Array2[i], sizeof(DATATYPE),1,FO) != 1) // write the struct to the DATABASE file
(gdb) p &Array2[i]
$24 = (DATATYPE *) 0x224b4
(gdb) p 0x224b4
$25 = 140468
(gdb) n
164 i++;
(gdb) p i
$26 = 0
(gdb) n
165 size = i;
(gdb) p size
$27 = 0
(gdb) n
128 while ( fgets( (char *) Line,1000,FI) != NULL) // fill buffer up to newline or eof or error
(gdb) p Line
$28 = "115\000DZA\000Algeria\000Africa\000Northern Africa\0002381741\0001962\00031471000\00069.7\00049982,Al-Jaza?\210\232?\211?ir/Alg?\210\232Ã rie,Republic,Abdelaziz Bouteflika,35,DZ\n\000", '?' <repeats 119 times>, "\000\000\000\000\000\000\000\000\000\b", '\0' <repeats 194 times>, "?77\000 \000\000\000??I\020\000\000\000\000\000\000\000\004??{d\000\000\000\024\000\000\000\b\000"...
(gdb) n
131 Tok = strtok( Line ,",\n"); // skip ID number
(gdb) p Line
$29 = "146,AGO,Angola,Africa,Central Africa,1246700,1975,12878000,38.3,6648,Angola,Republic,Jos?\210\232Ã Eduardo dos Santos,56,AO\n\000outeflika,35,DZ\n\000", '?' <repeats 119 times>, "\000\000\000\000\000\000\000\000\000\b", '\0' <repeats 194 times>, "?77\000 \000\000\000??I\020\000\000\000\000\000\000\000\004??{d\000\000\000\024\000\000\000\b\000"...
(gdb) n
133 Tok = strtok( NULL ,",\n"); // this should get the country code
(gdb) n
134 ActualStruct.code[0] = Tok[0];
(gdb) p Tok
$30 = 0xffbff39c "AGO"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ourhdr.h"
typedef struct // Country Data struct declaration
{
char code[4]; // Country Code
char name[50]; // Country Name
float life_expectancy; // Life Expentancy of the Country's citizen
int pop; // Country's Population
} DATATYPE;
typedef struct // Index Data struct declaration
{
char code[4];
long int offset; // offset of the data
} INDEX;
INDEX StructArray[300]; // for a lot of them
DATATYPE ActualStruct; // for a single struct
DATATYPE DatabaseArray[300]; // DATATYPE array
/****************************Add File***********************************************/
int addFile(DATATYPE* Array2, char* filename, int startHere)
{
int i = startHere;
int size = startHere;
char * Tok; // token from line
FILE *FI, *FO, *FO2;
char Line[1000]; // NO input line (delimited by \n) is longer than 1000
if((FI = fopen(filename, "r")) == NULL) // open a stream from "countries"
err_sys("Open Fail\n");
if((FO = fopen("DATABASE.txt", "a")) == NULL) // open a stream from "countries"
err_sys("Open DATABASE Fail\n");
if((FO2 = fopen("DIRECTORY.txt", "a")) == NULL) // open a stream from "countries"
err_sys("Open DIRECTORY Fail\n");
while ( fgets( (char *) Line,1000,FI) != NULL) // fill buffer up to newline or eof or error
{
Tok = strtok( Line ,",\n"); // skip ID number
Tok = strtok( NULL ,",\n"); // this should get the country code
ActualStruct.code[0] = Tok[0];
ActualStruct.code[1] = Tok[1];
ActualStruct.code[2] = Tok[2];
ActualStruct.code[3] = 0; // To create "string"
Tok = strtok( NULL ,",\n"); // this should get the country name
strncpy(&ActualStruct.name[0],Tok,50); // copy string at most 50 chars
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // this should get the population
ActualStruct.pop = atoi(Tok); // convert string to integer
Tok = strtok( NULL ,",\n"); // this one should get life expectancy
ActualStruct.life_expectancy = atof(Tok); // convert string to a floating point number
strcpy(Array2[i].code,ActualStruct.code); // get the current code
strcpy(Array2[i].name,ActualStruct.name); // get the current name
Array2[i].pop = ActualStruct.pop; // get the current population
Array2[i].life_expectancy = ActualStruct.life_expectancy; // get the current life expectancy
strcpy(StructArray[i].code, ActualStruct.code); // get the current code
StructArray[i].offset = ftell(FO); // get the current offset in the DATABASE file
if (fwrite(&Array2[i], sizeof(DATATYPE),1,FO) != 1) // write the struct to the DATABASE file
err_sys("fwrite error");
i++;
size = i;
}
/****************************Sort the array and write into DIRECTORY*****************************/
sort(StructArray,size); // call sort function
for (i=0; i<size; i++)
{
if (fwrite(&StructArray[i], sizeof(INDEX),1,FO2) != 1) // write the struct to the DIRECTORY file
err_sys("fwrite error");
}
if (fclose(FI)) // close file descriptor FI
err_sys("Close error\n");
if (fclose(FO)) // close file descriptor FO
err_sys("Close error\n");
if (fclose(FO2)) // close file descriptor FO2
err_sys("Close error\n");
return i;
}
/****************************************Main Function********************************************/
int main()
{
char userfile[50];
int count = 0;
int size = 0;
count = addFile(DatabaseArray,"AC1.txt",0);
/*********************************************MENU************************************************/
int c = -1;
while( c != 4)
{
printf("Please select an option (1 to 4):\n");
printf("1. Add to the DATABASE\n");
printf("2. Search the DATABASE\n");
printf("3. List all the countries in DATABASE by ordered Country Code\n");
printf("4. Press q to exit\n");
fflush(stdin);
c = -1; // error value if scanf fails
scanf("%d", &c);
switch (c)
{
case 1:
printf("Filename(data that you would like to add in): ");
scanf("%s",&userfile);
count = addFile(DatabaseArray, userfile, count);
break;
case 2:
search(size);
break;
case 3:
printsort(size);
break;
case 4:
puts("Exiting program!");
return 0;
default:
printf("\nNot implemented yet!");
}
}
}
(gdb) b main
Breakpoint 1 at 0x1177c: file sort1.c, line 193.
(gdb) r
Starting program: /home/ugrad/cpfoo/CS224/as2/MY
warning: Temporarily disabling breakpoints for unloaded shared library "/usr/lib/ld.so.1"
Breakpoint 1, main () at sort1.c:193
193 int count = 0;
(gdb) p count
$1 = 0
(gdb) n
194 int size = 0;
(gdb) p size
$2 = 0
(gdb) n
195 count = addFile(DatabaseArray,"AC1.txt",0);
(gdb)
203 if((infile = fopen("DIRECTORY.txt", "rb")) == NULL) // open a stream from "countries"
(gdb) p count
$3 = 7
(gdb) b printsort
Breakpoint 1 at 0x10e4c: file sort1.c, line 57.
(gdb) r
Starting program: /home/ugrad/cpfoo/CS224/as2/MY
warning: Temporarily disabling breakpoints for unloaded shared library "/usr/lib/ld.so.1"
Please select an option (1 to 4):
1. Add to the DATABASE
2. Search the DATABASE
3. List all the countries in DATABASE by ordered Country Code
4. Press q to exit
3
Breakpoint 1, printsort (size=0) at sort1.c:57
57 sort(StructArray,size); // call sort function
(gdb) n
59 if((FI = fopen("DATABASE.txt", "r")) == NULL) // open DATABASE for read
(gdb) p size
$1 = 0
int fun1() {
int abc;
...
}
int fun2() {
int abc;
...
}
/*************************Print Sorted Array**********************************************/
void printsort(int k)
{
DATATYPE country;
sort(StructArray,k); // call sort function
FILE *FI;
if((FI = fopen("DATABASE.txt", "r")) == NULL) // open DATABASE for read
err_sys("Open DATABASE Fail\n");
int i;
printf("--------------------------------------------------------------------------------------------------------\n");
printf(" CODE \t\t\t COUNTRY NAME \t\t\t POPULATION LIFE EXPECTANCY \t OFFSET\n");
printf("--------------------------------------------------------------------------------------------------------\n");
for (i=0; i<k; i++)
{
fseek(FI,StructArray(i).offset,SEEK_SET); //seek the offset in the binary file
fread(&country, sizeof(DATATYPE),1,FI); // read the struct of array from binary file (4 fields)
printf("%5s%50s%15u%18f%15u\n", country.code, country.name, country.pop, country.life_expectancy, StructArray[i].offset);
}
}
/************************Search Function by Country Code*********************************/
void search(int size)
{
int mid, lower = 0, upper = size, flag = 1;
INDEX cc;
FILE *FI;
if((FI = fopen("DATABASE.txt", "r")) == NULL) // open DATABASE for read
err_sys("Open DATABASE Fail\n");
printf("Enter Country Code to search: ");
scanf("%s", &cc);
for(mid = (lower+upper)/2; lower <= upper; mid = (lower + upper)/2)
{
if(strcmp(StructArray[mid].code, cc.code) == 0) // compare the input with the sorted array
{
printf("The country code is at position %d in the array at offset %u in the binary file.\n", mid, StructArray[mid].offset);
fseek(FI,StructArray[mid].offset,SEEK_CUR); //seek the offset in the binary file
fread(&DatabaseArray[mid], sizeof(DATATYPE),1,FI); // read the struct of array from binary file (4 fields)
printf("%s %s %u %f\n", DatabaseArray[mid].code, DatabaseArray[mid].name, DatabaseArray[mid].pop, DatabaseArray[mid].life_expectancy);
flag = 0;
break;
}
if(strcmp(StructArray[mid].code, cc.code) > 0) // compare the input with the sorted array
upper = mid - 1;
else
lower = mid + 1;
}
if (flag)
printf("Elements not found."); // print this if the input is not in the array
if (fclose(FI)) // close file descriptor FI
err_sys("Close error\n");
}
/****************************Add File***********************************************/
int addFile(DATATYPE* Array2, char* filename, int startHere)
{
int i = startHere;
int size = startHere;
int k = startHere;
char * Tok; // token from line
FILE *FI, *FO, *FO2;
char Line[1000]; // NO input line (delimited by \n) is longer than 1000
if((FI = fopen(filename, "r")) == NULL) // open a stream from "countries"
err_sys("Open Fail\n");
if((FO = fopen("DATABASE.txt", "a")) == NULL) // open a stream from "countries"
err_sys("Open DATABASE Fail\n");
if((FO2 = fopen("DIRECTORY.txt", "a")) == NULL) // open a stream from "countries"
err_sys("Open DIRECTORY Fail\n");
while ( fgets( (char *) Line,1000,FI) != NULL) // fill buffer up to newline or eof or error
{
Tok = strtok( Line ,",\n"); // skip ID number
Tok = strtok( NULL ,",\n"); // this should get the country code
ActualStruct.code[0] = Tok[0];
ActualStruct.code[1] = Tok[1];
ActualStruct.code[2] = Tok[2];
ActualStruct.code[3] = 0; // To create "string"
Tok = strtok( NULL ,",\n"); // this should get the country name
strncpy(&ActualStruct.name[0],Tok,50); // copy string at most 50 chars
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // skip
Tok = strtok( NULL ,",\n"); // this should get the population
ActualStruct.pop = atoi(Tok); // convert string to integer
Tok = strtok( NULL ,",\n"); // this one should get life expectancy
ActualStruct.life_expectancy = atof(Tok); // convert string to a floating point number
strcpy(Array2(i).code,ActualStruct.code); // get the current code
strcpy(Array2(i).name,ActualStruct.name); // get the current name
Array2(i).pop = ActualStruct.pop; // get the current population
Array2(i).life_expectancy = ActualStruct.life_expectancy; // get the current life expectancy
strcpy(StructArray(i).code, ActualStruct.code); // get the current code
StructArray(i).offset = ftell(FO); // get the current offset in the DATABASE file
if (fwrite(&Array2(i), sizeof(DATATYPE),1,FO) != 1) // write the struct to the DATABASE file
err_sys("fwrite error");
i++;
size = i;
k = size;
}
/****************************Sort the array and write into DIRECTORY*****************************/
sort(StructArray,size); // call sort function
for (i=0; i<size; i++)
{
if (fwrite(&StructArray(i), sizeof(INDEX),1,FO2) != 1) // write the struct to the DIRECTORY file
err_sys("fwrite error");
}
if (fclose(FI)) // close file descriptor FI
err_sys("Close error\n");
if (fclose(FO)) // close file descriptor FO
err_sys("Close error\n");
if (fclose(FO2)) // close file descriptor FO2
err_sys("Close error\n");
return i;
}
/****************************************Main Function********************************************/
int main()
{
char userfile[50];
int count = 0;
int size = 0;
int k = 0;
count = addFile(DatabaseArray,"AC1.txt",0);
/*********************************************MENU************************************************/
int c = -1;
while( c != 4)
{
printf("Please select an option (1 to 4):\n");
printf("1. Add to the DATABASE\n");
printf("2. Search the DATABASE\n");
printf("3. List all the countries in DATABASE by ordered Country Code\n");
printf("4. Press q to exit\n");
fflush(stdin);
c = -1; // error value if scanf fails
scanf("%d", &c);
switch (c)
{
case 1:
printf("Filename(data that you would like to add in): ");
scanf("%s",&userfile);
count = addFile(DatabaseArray, userfile, count);
break;
case 2:
search(size);
break;
case 3:
printsort(k);
break;
case 4:
puts("Exit program!");
return 0;
default:
printf("\nNot implemented yet!");
}
}
}
int speed; // the speed (mph) of the train
So, I advise you to fully comment your code explaining the definition of the variables and blocks of code. These comments will represent your design.
Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.
Have a better answer? Share it in a comment.
From novice to tech pro — start learning today.
>> but why there is something are 0 like ActualStruct.pop (run in the first line)
Don't know since you didn't p Line so not sure how well the parsing went.
>> but the i and size is increasing everytime runs the while loop?
In you OP are these 2 LOCs:
i++;
size = i;
so that explains why they are increasing.
(1) I wrote:
>> let me know what value of count are your getting everytime you return from addFile.
What should the value be? What value did you get? Is it correct?
(2) I wrote:
>> Step through the debugger, and when you hit the option 3 (as in your OP), then determine what are the values of the parameters that go into the function you are calling.
Why didn't you post these two results? I can only help if we work together. Otherwise, it will take too long to solve the problem.
To keep debugging simple, just have a file with 2-3 entries so that you don't spend a lot of time looping.