-1

The problem(actually various problems):

  1. if choice != 0 either the insert_text function is called or add_word_in_dictionary is called which is not wanted..

  2. I want to create a function which saves a file.Thus, I created the save_file function but I am not that sure if it actually 'saves' the file..

  3. the count_difrnt_words function..With this function I want to count how many different words are in a file but I do not know the length of each string-word in the file so I guess fgets can't be used in this occasion..

The englishWords.txt is a large file with words like this https://prnt.sc/3BKsO7_Ud2XG

and the other file that is used,is a 'common' .txt file with words,special characters,spaces between words etc..

The code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int get_choice(void);
int check_word(char *word);
void insert_text(FILE ** p_fp);
char *add_word(void);
void add_word_in_dictionary(FILE ** p_fp);
void save_file(FILE **fp);
int count_characters(FILE **fp);
int count_spaces(FILE **fp);


int main()
{
    FILE *fp;
    FILE *fp2;  /*fp for Alice....txt and fp2 for englishWords.txt */
    int choice = 0;
    while(1)
    {
        choice = get_choice();

        if(choice == 0)
        {
            insert_text(&fp);
        }

        if(choice == 1);
        {
            add_word_in_dictionary(&fp2);
        }

        if(choice == 2)
        {
            printf("\n You have entered correction mode but in this 
version, nothing happens \n");
        }

        if(choice == 3)
        {
            save_file(&fp);
            printf("\n The file has been saved \n");
        }

        if(choice == 4)
        {
            count_characters(&fp);
            count_spaces(&fp);
            count_difrnt_words(&fp);


        }

        if(choice == 5)
        {
            break;
        }

    }

    printf("\n The program has ended \n");
    return 0;
}



int get_choice(void) {
    int choice = 0;
    printf("\n Select a choice from  the below \n");
    printf("\n Select 0 to add text \n");
    printf("\n Select 1 to add new words in the dictionary \n");
    printf("\n Select 2 to enter  enter correction mode \n");
    printf("\n Select 3 to save the text \n");
    printf("\n Select 4 to see the statistics about your text \n");
    printf("\n Select 5 to exit the program\n");
    scanf("\n%d", &choice);
    return choice;
}



int check_word(char *word)
{
    FILE *readfile;
    char word1[40];
    readfile = fopen("englishWords.txt","r");

    if(!readfile)
    {
        printf("\n There was an error opening the file \n");
        return;
    }

    while(fscanf(readfile,"%s",word1) != EOF)
    {
        if(strcmp(word,word1) == 0)
        return 1;

        else
        {
            return 0;
        }
    }

    fclose(readfile);
}



void insert_text(FILE ** p_fp)
{
    *p_fp = fopen("AlicesAdventuresInWonderland.txt", "a+");
    fprintf(*p_fp, "%99s\n",add_word());
    return;
}



char *add_word(void)
{
    char string[100] = {""};
    printf("\n Please enter the word \n");
    scanf("\n%[^\n]", &string);
    return string;
}



void add_word_in_dictionary(FILE ** p_fp)
{
    *p_fp = fopen("englishWords.txt","a+");
    fprintf(*p_fp, "%99s\n",add_word());
    return;
}



 void save_file(FILE **fp)
{
    fclose(*fp);
    return;
}



int count_characters(FILE **fp)
{
    char ch;
    int count_ch = 0;
    *fp = fopen("AlicesAdventuresInWonderland.txt", "r");
    if(*fp == NULL)
    {
        printf("\n There was an error opening the file \n");
        return;
    }

    while(ch != EOF)
    {
        if(ch != ' '  && ch !=  '\n')
        {
            count_ch++;
        }
        ch=fgetc(*fp);
    }

    fclose(*fp);

    return count_ch;
}



int count_spaces(FILE **fp)
{
    int count_sp;
    char c;
    *fp = fopen("AlicesAdventuresInWonderland.txt","r");
     while ((c = fgetc(*fp)) != EOF)
    {
        if (c == ' ')
            count_sp++;
    }

    return count_sp;
}

int count_difrnt_words(FILE **fp)
{
    int i;
    int num = 0;
    char str[15];
    char c;
    *fp = fopen("AlicesAdventuresInWonderland.txt","r");
    while((c = fgetc(*fp)) != EOF)
        {
           fgets(str,15,*fp);
           if(strcmp(fgets(str,15,*fp),fgets(str,15,*(fp+i))))
        {
        num++;
        }

        i++;

    }

    return num;
}
George S
  • 51
  • 7
  • You have multiple problems, but the worst I think is the `add_word` function which returns a pointer to a local variable. The life-time of local variables (like the `string` array variable) ends when the function returns, i.e. the variable ceases to exist. Any pointer to such a variable will become immediately invalid, and using them will lead to *undefined behavior*. – Some programmer dude Apr 19 '22 at 11:43
  • So,if i just remove the pointer from the prototype of *add_word* is a good move? – George S Apr 19 '22 at 11:47
  • No that won't work. Instead of using a local variable, pass the array (or rather a pointer to its first element) as an argument, – Some programmer dude Apr 19 '22 at 11:55
  • Also note that the `%[]` format for `scanf` expect a `char *` argument. You current pass an argument of the type `char (*)[100]`. Mismatching format specifier and argument type also leads to *undefined behavior*. Remove the pointer-to operator in the `scanf` call when reading strings, so instead of `&string` use only plain `string`. – Some programmer dude Apr 19 '22 at 11:57
  • For the first one,you mean in *insert_text* function,right? – George S Apr 19 '22 at 12:02
  • If you change the arguments for `add_word` you must change all places where you call it as well. Which means `insert_text` as well as `add_word_in_dictionary`. – Some programmer dude Apr 19 '22 at 12:04
  • But if i change the arguments of *add_word* that means I have to add *scanf* in *main*,right? – George S Apr 19 '22 at 12:09
  • `There was an error opening the file` is the canonical example of a useless error message. What was the error? Which file was being opened? Try: `const char *path = "AlicesAdventuresInWonderland.txt"; if( (fp = fopen(path, "r")) == NULL ){ perror(path); ...` – William Pursell Apr 19 '22 at 12:23
  • I will have that in mind but I am a beginner (as you can judge by the code).. @William Pursell – George S Apr 19 '22 at 12:26
  • You have `if(choice == 1);` so that `add_word_in_dictionary()` is called unconditionally because of the unwanted semicolon. – Jonathan Leffler Apr 19 '22 at 12:37
  • @JonathanLeffler Yep,I fixed that...But I am still having serious problems in 2,3 .-. – George S Apr 19 '22 at 12:39
  • Normally, you would use something like `if (choice == 0) { … } else if (choice == 1) { … } else if (choice == N) { … } else { …handle unexpected choice value… }`. Whether that's relevant to your "serious problems in 2,3" I'm not sure. – Jonathan Leffler Apr 19 '22 at 12:51
  • Your `save_file()` function merely closes a file stream via a pointer to file stream. It doesn't even set the pointer to null, which would be a justification for passing a pointer to a file stream. It is not clear how that 'saves' a file. It is not clear what you mean by saving a file. It writes nothing, so only what's already been written is in the file. You have to decide what the function is supposed to do and then implement it. At the moment (IMO), it is, at best, a dummy function that does not live up to its name at all. (Is that enough prevarication?) – Jonathan Leffler Apr 19 '22 at 12:55
  • Well,in the exercise I am asked to do one of the requirements is to have a choice that if the user selects it saves the file (it does not specify anything else for this .-.) so I decided to create function which 'saves the file'- it might be unecessary though.. – George S Apr 19 '22 at 13:01

1 Answers1

1

Your add_word function return a pointer to a local variable. Local variables cease to exists immediately when the function ends (the life-time of the variable ends together with the function return).

Any pointer to a local variable will become invalid and can't be used. Using it anyway will lead to undefined behavior.

I suggest you change the add_word function to accept the array as an argument instead:

char *add_word(char *word)
{
    printf("\n Please enter the word \n");
    scanf(" %100[^\n]", word);
    return word;
}

This change means you have to change how you call it, and that the array needs to be defined in the calling function instead.

For example:

void insert_text(FILE ** p_fp)
{
    *p_fp = fopen("AlicesAdventuresInWonderland.txt", "a+");

    char word[100];
    fprintf(*p_fp, "%s\n", add_word(word));
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621