1

Ok. I have this simple "test" code in which i am trying to achieve a perfect ctrl-c capture process, so that i can transfer it to my main project. Now, The capturing of the ctrl-c works perfectly fine, but the things that come after that are not what i expected.

For instance, if the user clicked ctrl-c right at the beginning of the code, the code enters the ctrl-c condition from: Hi. Name please:, then if the user pressed ctrl-c accidentally and wants to return to code, shouldn't it return back to asking the user's name? But it skips to asking Day number 2. Enter amount saved: which is like two inputs away, from the name then to the first day then to the second day. How am i supposed to modify the capture function so that it returns back to where it left off, and not after that?

Code:

#include <stdio.h>
#include <stdlib.h>  //For Functions such as exit(0) and system("pause")
#include <signal.h>
#define DAYS 7

void siginthandler(int sig_mun){
    char H;
    system("cls");
    signal(SIGINT, siginthandler);
    printf("[+] CRITICAL STOP [+]\nOuch! Did you just press ctrl-c?\nSo You want to exit?\nY to exit.\nN not to exit.\n\nYour input: ");
    scanf(" %c", &H);
    if (H == 'Y'){
    system("cls");
        printf("Exited");
        exit(0);
        } else {
            fflush(stdout);
        }
}
main(){
    signal(SIGINT, siginthandler);
    int num = 1;
    float ave, amt, tot = 0, WC = 1, Wave, WD;
    char nme[40], F;
    
    printf("Hi. Name please: ");
    scanf("%s", &nme);
    printf("Dear %s, we will be calculating your daily average savings.\nType your saved amt per day sccordingly.\n\n", nme);
    while (1){
    while (num <= DAYS){
        printf("Day number %d. Enter amount saved: ", num);
        scanf("%f", &amt);
        if (amt < 0){
            printf(" Wrong! Please retype\n\n");
            } else {
        num = num + 1;
        tot = tot + amt;
    }
    }
    printf("Total amount saved till now: %f\n", tot);
    ave = tot / DAYS;
    printf("Average is %.2f per day.\n\n", ave);
    printf("Wanna continue?\nInput (y/n): ");
    scanf(" %c", &F);
    if (F == 'n' && WC == 1){
        WD   = tot;
        Wave = WD;
        printf("You have Input %.0f week\'s data.\n", WC);
        printf("You have saved %.2f per week in average.\n", Wave);
        system("pause");
        exit(0);
        
        } else if (F == 'n' && WC > 1){
            printf("You have input %.0f week\'s data.\n", WC);
            WD   = WD + tot;
            Wave = WD / WC;
            printf("You have saved %.2f per week in average.\n", Wave);
            system("pause");  //Allows user to enter a key allowing the program exits
            exit(0);  //Exit code
            } else if (F == 'y'){
            num = 1;
            WC  = WC + 1;
            WD  = WD + tot;
            tot = 0;
            }
    }
    return 0;
}

UnfreeHeX
  • 83
  • 1
  • 9
  • 6
    Note that your signal handler is using functions that are not [*async-signal-safe*](https://man7.org/linux/man-pages/man7/signal-safety.7.html). – Fred Larson Jul 06 '20 at 12:51
  • Not sure I understand your question : are you expecting that the `printf("Hi. Name please: ");` is repeated after the signal handler has finished ? That's not how signal handlers work. – Sander De Dycker Jul 06 '20 at 13:10
  • @SanderDeDycker No i mean signal handlers dont come back to where they left the code? – UnfreeHeX Jul 06 '20 at 13:13
  • There are more common methods to use for user interaction. Why have you chosen to use `ctrl-c`? – ryyker Jul 06 '20 at 13:14
  • _signal handlers dont come back to where they left the code?_... It depends on what code is called in the signal handler. Not when `exit()` is called. `exit()` terminates the calling process immediately. – ryyker Jul 06 '20 at 13:17
  • @UnfreeHeX : a signal interrupts the current thread to run the signal handler, and when the signal handler has finished, the current thread (assuming it's still running) should resume where it was interrupted. If the behavior you observe is different, there's a good chance it's because of Fred Larson's comment above. – Sander De Dycker Jul 06 '20 at 13:18
  • @ryyker Yes i know that when input is Y, the code exits. but when its N, why does it not go back to its original state. – UnfreeHeX Jul 06 '20 at 13:21
  • Does this answer your question? [How to avoid using printf in a signal handler?](https://stackoverflow.com/questions/16891019/how-to-avoid-using-printf-in-a-signal-handler) – Sander De Dycker Jul 06 '20 at 13:21
  • @SanderDeDycker So i am in a dead end? There is not way out i think. I am doing this whole capturing of ctrl-c because my project requires the user to exit whenever he wants to exit. i wanted to add in the part of 'accidental click' instead of just exit(0). – UnfreeHeX Jul 06 '20 at 13:23
  • @SanderDeDycker So does it mean that using printf and a character within the capturing code, causes the problem right? – UnfreeHeX Jul 06 '20 at 13:28
  • _why does it not go back to its original state._. Read the very first paragraph of the link in Larson's comment. You could be experiencing undefined behavior as if any of your calls are not re-entrant, or in any other way not thread safe, then if could lead to a failure to return. – ryyker Jul 06 '20 at 13:28
  • @UnfreeHeX : your signal handler could simply set a variable to some chosen value. In your main loop, you can then check that variable. If the variable now has your chosen value, you can then ask the question if the user wants to exit (still in the main loop) and either exit, or continue. – Sander De Dycker Jul 06 '20 at 13:32
  • @SanderDeDycker So use : `if (SIGINT ...){ ask if want to exit }` – UnfreeHeX Jul 06 '20 at 13:35
  • But even this gives no output when ctrl-c is clicked. `void siginthandler(int sig_mun){ signal(SIGINT, siginthandler); } main(){ signal(SIGINT, siginthandler); if (((signal(SIGINT, siginthandler)) == true) == true){ printf("\n\nStopped"); }` – UnfreeHeX Jul 06 '20 at 13:46
  • `main()` is wrong (should be `int main(void)`. `scanf("%s", &nme);` is wrong (should be scanf("%s", nme);`. The compiler should have warned you in both cases. If it didn't, you need to upgrade. – n. m. could be an AI Jul 06 '20 at 13:48
  • @FredLarson Since OP is using `system("cls")`, chances that they are on a Posix-ish system are slim. There are no function that are safe to call from a signal handler as far as C is concerned. The only permissible action is to set a `volatile sig_atomic_t` variable and return. – n. m. could be an AI Jul 06 '20 at 14:06
  • @SanderDeDycker Its ok. I just changed the whole concept. When the user clicks cancel, i used `goto` to the start of the programme, and also printing that cause they clicked cancel, they will be returned to the main menu. – UnfreeHeX Jul 11 '20 at 11:50

0 Answers0