Complementary task for topic: 9

M Nemeth � 2023-08-29 15:21:04.631218'

File Handling: save array

File Handling: save array

Complete our dictionary program with reading and writing the database into a file. The program code was:

#include
#include
#include
typedef struct {
char* word;
char* meaning;
} DictionaryEntry;
void clearInputBuffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF) {}
}
void addWord(DictionaryEntry** dictionary, int* wordCount) {
DictionaryEntry newWord;
printf("Enter the word: ");
//scanf("%s", &newWord.word); Will not work! try out!
//Dynamic read is complicated
char c=getchar();
int size=1;
char* str=(char*)malloc(size*sizeof(char));
str[0]='\0';
while(c!='\n'){
str=(char*)realloc(str,++size*sizeof(char));
str[size-2]=c;
str[size-1]='\0';
c=getchar();
}
newWord.word=str;
printf("Enter the meaning: ");
//scanf("%s", &newWord.meaning); Will not work! try out!
c=getchar();
size=1;
str=(char*)malloc(size*sizeof(char));
str[0]='\0';
while(c!='\n'){
str=(char*)realloc(str,++size*sizeof(char));
str[size-2]=c;
str[size-1]='\0';
c=getchar();
}
newWord.meaning=str;
(*wordCount)++;
*dictionary = (DictionaryEntry*)realloc(*dictionary, (*wordCount) * sizeof(DictionaryEntry));
(*dictionary)[*wordCount - 1] = newWord;
printf("Word added successfully!\n");
}
void searchMeaning(DictionaryEntry* dictionary, int wordCount, char* searchWord) {
int found = 0;
for (int i = 0; i < wordCount; i++) {
if (strcmp(dictionary[i].word, searchWord) == 0) {
printf("Meaning: %s\n", dictionary[i].meaning);
found = 1;
break;
}
}
if (!found) {
printf("Word %s not found in the dictionary.\n",searchWord);
}
}

int main() {
int wordCount = 0;
DictionaryEntry* dictionary = NULL;
int choice;
char searchWord[100];
printf("--- Dictionary Application ---\n");
while (1) {
printf("1. Add new word\n");
printf("2. Search for meaning\n");
printf("3. Exit\n");
printf("\nEnter your choice: ");
scanf("%d", &choice);
clearInputBuffer();
switch (choice) {
case 1:
addWord(&dictionary, &wordCount);
break;
case 2:
printf("Enter the word to search: ");
scanf("%99s", searchWord);
clearInputBuffer();
searchMeaning(dictionary, wordCount, searchWord);
break;
case 3:
printf("Exiting... Goodbye!\n");
// Deallocate the memory used by the dictionary
for (int i = 0; i < wordCount; i++) {
free(dictionary[i].word);
free(dictionary[i].meaning);
}
free(dictionary);
return 0;
default:
printf("Invalid choice. Try again.\n");
}
}
return 0;
}

Hint: The database logic is up to you, basically it is a good practice to write CSV (comma separated values), as it usually recognized by any other program. Header is not a must, but if it is there you need to be careful, when reading!
feof() becomes true is we reached the end of file.
saveing is nearly the same as print to the screen, use fprintf(), when you read you need to build up the database. That is nearly the same as get the data from the keyboard!

Solution
#include 
#include 
#include 
 
typedef struct {
    char* word;
    char* meaning;
} DictionaryEntry;
 
 
 
void addWord_from_file(DictionaryEntry** dictionary, int* wordCount,FILE* F) {
DictionaryEntry newWord;
    //scanf("%s", &newWord.word); Will not work! try out!
    //Dynamic read is complicated
    char c=fgetc(F);
    if (c==EOF) //do not try to read after the last line
        return;
    int size=1;
    char* str=(char*)malloc(size*sizeof(char));
    str[0]='\0';
    while(c!=','){
 
        str=(char*)realloc(str,++size*sizeof(char));
        str[size-2]=c;
        str[size-1]='\0';
        c=fgetc(F);
    }
    newWord.word=str;
 
   // printf("Enter the meaning: ");
    //scanf("%s", &newWord.meaning); Will not work! try out!
    c=fgetc(F);
    size=1;
    str=(char*)malloc(size*sizeof(char));
    str[0]='\0';
    while(c!='\n'){
 
        str=(char*)realloc(str,++size*sizeof(char));
        str[size-2]=c;
        str[size-1]='\0';
        c=fgetc(F);
    }
    newWord.meaning=str;
 
    (*wordCount)++;
    *dictionary = (DictionaryEntry*)realloc(*dictionary, (*wordCount) * sizeof(DictionaryEntry));
    (*dictionary)[*wordCount - 1] = newWord;
 
}
 
int read_DB(DictionaryEntry** dictionary, int* wordCount){
FILE* F=fopen("data.txt","r");
if(F==NULL){
    return -1;
}
while(!feof(F))
    addWord_from_file(dictionary,wordCount,F);
fclose(F);
return 0;
}
 
 
int write_DB(DictionaryEntry* dictionary, int wordCount){
FILE* F=fopen("data.txt","w");
if(F==NULL){
    return -1;
}
for(int i=0; ifprintf(f,"%s,%s\n",dictionary[i].word,dictionary[i].meaning);="" }="" fclose(f);="" return="" 0;="" void="" clearinputbuffer()="" {="" int="" c;="" while="" ((c="getchar())" !="\n" &&="" c="" {}="" addword(dictionaryentry**="" dictionary,="" int*="" wordcount)="" dictionaryentry="" newword;="" printf("enter="" the="" word:="" ");="" scanf("%s",="" &newword.word);="" will="" not="" work!="" try="" out!="" dynamic="" read="" is="" complicated="" char="" size="1;" char*="" str="(char*)malloc(size*sizeof(char));" str[0]="\0" ;="" while(c!="\n" ){="" str[size-2]="c;" str[size-1]="\0" newword.word="str;" meaning:="" &newword.meaning);="" newword.meaning="str;" (*wordcount)++;="" *dictionary="(DictionaryEntry*)realloc(*dictionary," (*wordcount)="" *="" sizeof(dictionaryentry));="" (*dictionary)[*wordcount="" -="" 1]="newWord;" printf("word="" added="" successfully!\n");="" searchmeaning(dictionaryentry*="" wordcount,="" searchword)="" found="0;" for="" (int="" i="0;" <="" wordcount;="" i++)="" if="" (strcmp(dictionary[i].word,="" 0)="" printf("meaning:="" %s\n",="" dictionary[i].meaning);="" break;="" (!found)="" %s="" in="" dictionary.\n",searchword);="" main()="" wordcount="0;" dictionaryentry*="" dictionary="NULL;" choice;="" searchword[100];="" (read_db(&dictionary,&wordcount)="=-1)" printf("could="" find="" an="" existing="" database");="" printf("---="" application="" ---\n");="" (1)="" printf("1.="" add="" new="" word\n");="" printf("2.="" search="" meaning\n");="" printf("3.="" exit\n");="" printf("\nenter="" your="" choice:="" scanf("%d",="" &choice);="" clearinputbuffer();="" switch="" (choice)="" case="" 1:="" addword(&dictionary,="" &wordcount);="" 2:="" word="" to="" search:="" scanf("%99s",="" searchword);="" searchmeaning(dictionary,="" 3:="" printf("exiting...="" goodbye!\n");="" if(-1="=write_DB(dictionary,wordCount))" printf("cannot="" save="" file");="" deallocate="" memory="" used="" by="" free(dictionary[i].word);="" free(dictionary[i].meaning);="" free(dictionary);="" default:="" printf("invalid="" choice.="" again.\n");="" code="">

Explanation
The addWord and the addWord_from_file functions nearly the same, could we do both functionality in the same function?

Yes, we need to get a new argument, the stream, it can be the STDIN, or the file pointer. fprintf() fscanf() fgetc() fputc() etc. works as printf() scanf()... if we use the stdin as first parameter.
< < previous    next > >