0

Okay, quick context. This program needs to read up to 50 characters, display a menu and do functions. First function is searching something given by the user in the 50 character array it made earlier. Edit: Right now everything works as intended, except if you input 50 or more characters, the "menu" print happens twice.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int search(char arr[], int size1);
int main(){
    int fun, funct, i, size1, quit=0, c;
    char arr[50];
    printf("Please input up to 50 characters.\n");
    fgets(arr, 51, stdin);
    size1=strlen(arr);
    while (quit==0){
        printf("Please choose a function:\n1. Search for 
        character.\n2. Replace character.\n3. Look for 
        palindrome.\n4. Quit.\n");
        scanf("%d", &fun);
        while ( (c = getchar()) != EOF && c != '\n' );
        switch (fun){
            case 1:
                funct=search(arr,size1);
                break;
            case 2:
                break;
            case 3:
                break;
            case 4:
                quit=1;
                printf("Now quitting...");
                break;
        }
    }
}
int search(char arr[], int size1){
    char sear[50];
    int i, j, e, size2=60, foundn=0, pos[50], y=0, b, m;
    while (size2>size1){
        printf("Input up to %d characters to search.\n", size1);
        gets(sear);
        size2=strlen(sear);
        if (size2>size1){
            printf("Input longer than %d characters.\n", size1);
        }
    }
    for (m=0;m<50;m++){
        pos[m]=100;
    }
    for (j=0;j<size1;j++){
        if (arr[j]==sear[0]){
            e=j;
            for (i=1;i<size2;i++){
                e++;
                if (arr[e]==sear[i]){
                    if (i==(size2-1)){
                        foundn++;
                        pos[y]=j;
                        y++;
                    }
                }
            }
        }
    }
    if (foundn>0){
        printf("Searched characters appear %d times in position(s): 
        ",foundn);
        for (b=0;pos[b]!=100;b++){
            printf("%d.\n", pos[b]);
        }
    }
    else {
        printf("Characters do not appear in string.\n");
    }
}
  • 2
    One issue: `size2` is an uninitialised variable. So `while (size2>size1)` is using an indeterminate value and the result is undefined behaviour. "*I tried the logic with pen and paper*". Good start. The next step is to debug the running program. Use a debugger to step thru the code and examine it as it runs. – kaylum Jan 19 '22 at 00:42
  • 1
    When the first iteration of `while (size2>size1)` is executed `size2` is uninitialized. You should read [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – Retired Ninja Jan 19 '22 at 00:42
  • 1
    `goto menu;` Using `goto` like this is bad practice and strongly discouraged. Write and call a function instead or use a proper loop construct like `while`. – kaylum Jan 19 '22 at 00:44
  • 1
    There are valid uses for `goto`. This is not one of them. – klutt Jan 19 '22 at 12:04
  • First of all thanks everyone for the replies. Now for the size2 I just forgot to initialise it, i wanted it to be something like 60 just so it enters the while once. I've read all about fgets and gets, so I should swap the gets with fgets(sear, size1, stdin)? Should work, I'll try it. As for the goto, I know it's bad to use, but for some reason I just couldn't get the while loop to work. I had while(quit=o) {switch...} but the program just didn't work. – Spyros Fronimos Jan 19 '22 at 12:29
  • After trying with fgets instead of gets and while instead of goto I got these results: with fgets when I enter more than the maximum size it outputs some weird symbols and stuff, which I'd like to avoid. Figured out the while, removed goto, will update code – Spyros Fronimos Jan 19 '22 at 12:36
  • 1
    Unrelated: `char arr[50]; ... fgets(arr, 51, stdin);` is an accident waiting to happen. Either increase the size of the array (`char arr[51];`) or decrease the maximum amount read be `fgets()` (`fgets(arr, 50, stdin);`). Even better: use `sizeof` inside fgets: `fgets(arr, sizeof arr, stdin);` – pmg Jan 19 '22 at 12:38
  • Reason i put 51 in fgets is because I read it also stores \n, but I guess if the user inputs 51 characters then it all goes downhill huh. Will do – Spyros Fronimos Jan 19 '22 at 12:42
  • with sizeof if you input 50 characters, it will store 49 and also somehow break the program. same with my 51, but it stores 50 characters instead. When I say break, it prints the "menu" twice before letting the user choose an action. After that program works as intended, but menu is printed twice the first time it's printed – Spyros Fronimos Jan 19 '22 at 12:49
  • 1
    If there's more input than will fit in the buffer, `fgets` leaves the rest on standard input. So it will try to read some portion of the remaining input line as `fun`. That won't work, so `fun` will contain a random value, which probably won'g be 1 or 4, so you'll take another trip around your `while (quit==0)` loop, and prompt for more input. – Steve Summit Jan 19 '22 at 13:07
  • It's a good habit to always check `scanf`'s return value: `int r = scanf("%d", &fun); if(r != 1) printf("invalid input\n");` – Steve Summit Jan 19 '22 at 13:09
  • Hmm I see, yea it appears that exactly what you said happens Steve. How would one go about fixing that though? – Spyros Fronimos Jan 19 '22 at 16:10
  • regarding: `fgets(arr, 51, stdin);` This is an error. because there are only 50 characters in the input buffer, not 51 – user3629249 Jan 20 '22 at 03:10
  • regarding `gets(sear);` the function has been depreciated for many years and completely removed from the language around 2009. suggest using `fgets()` instead of `gets()` – user3629249 Jan 20 '22 at 03:15
  • regarding: `size2=strlen(sear);` the function: `strlen()` returns a `size_t`, not an `int` – user3629249 Jan 20 '22 at 03:17
  • regarding: `while(quit=o) {switch...}` the `quit=0` is an assignment, not a comparison.. Suggest: `quit == 0` – user3629249 Jan 20 '22 at 03:19
  • Thanks everyone for your help! The program now works exactly like I need it to. Except that if I input more than 50 characters, it then crashes upon entering less than 50. – Spyros Fronimos Jan 20 '22 at 23:58

0 Answers0