Why when entering in C instead of a digit, indicate any letter or value instead of a comma a point in a fractional program, the program loops? Sample program:

#include <stdio.h> #include <stdlib.h> #include <locale.h> main() { setlocale (LC_ALL, "rus"); int number_account = 0; float start_balance, TotalCost, TotalCredit, ExtendOfCredit, NewBalance, Balance; while (number_account != -1) { printf("Number account - "); scanf("%d", &number_account); printf("start_balance: "); scanf("%f", &start_balance); printf("TotalCost: "); scanf("%f", &TotalCost); printf("TotalCredit: "); scanf("%f", &TotalCredit); printf("ExtendOfCredit: "); scanf("%d", &ExtendOfCredit); NewBalance = start_balance + TotalCost - TotalCredit; if (NewBalance > ExtendOfCredit) { printf("number_account: %d", number_account); printf("ExtendOfCredit: %.2f", ExtendOfCredit); printf("Balance: %.2f\n \n", Balance = start_balance + TotalCredit); } } system("PAUSE"); } 

    1 answer 1

    @steelhouse , you should always check the value returned by each scanf() (see man 3 scanf , but in your case, it’s okay 1) and correctly program error handling.

    UPD

    @steelhouse , as promised about scanf .

    This function tries to enter the ordered number of arguments (in accordance with the format) and returns the number of successfully read arguments or EOF (in the case of the end of the input stream (file)).

    When reading a number, scanf first skips delimiters (space, tabulation, new line character, etc.), and then converts the string of digits into a decimal number (of course, the + or - sign is allowed). As soon as a non-digit scanf is encountered, it proceeds to read the next argument, but this “non-numeric” remains in the stream !!! .

    That’s why your program loops. You read the numbers and if a letter is encountered (or another, unsuitable character in the format), it remains. The next scanf tries to read it and leaves it in the stream, etc.

    The solution is to analyze the number returned by scanf . If it is less than expected (and not EOF (by EOF, you probably need to complete all input)), then you need to skip all the characters to a new line .

    Here is a small example.

     #include <stdio.h> #include <stdlib.h> // прочтем все символы до новой строки // вернем (для любопытных) их количество // или EOF (для анализа конца файла (это уже не пустое любопытство)) static int skip() { int c, n = 0; if (!feof(stdin)) // убедимся, что нужно читать while ((c = getchar()) != EOF) { n++; if (c == '\n') return n; } return EOF; } int main () { int a, b, i = 0, rc; while (rc != EOF) { printf ("Enter a,b: "); fflush(stdout); rc = scanf("%d%d",&a,&b); printf ("rc = %da = %db = %d\n", rc,a,b); #if ERRDEMO if (rc == 2) i = 0; else if (++i > 5) break; #else if (rc != EOF) if (rc != 2) { printf ("Input error rc = %d\n",rc); printf ("skip %d characters\nTry again ",rc = skip()); } #endif } exit (0); } 

    #if ERRDEMO

    #else ...

    #endif

    it is (if you do not know yet) conditional compilation directives. Those. if you compile

     gcc ac 

    then the code will be compiled between #else and #endif, and if

     gcc -DERRDEMO ac 

    then the code is between #if and #else. Naturally, the code outside #if .... #endif is always compiled.

    Now look at the results (and you can also collect it under Windows (gcc checked) and try different options)

     avp@avp-xub11:~/hashcode$ gcc ac -DERRDEMO avp@avp-xub11:~/hashcode$ ./a.out Enter a,b: 1 2 rc = 2 a = 1 b = 2 Enter a,b: 3 a rc = 1 a = 3 b = 2 Enter a,b: rc = 0 a = 3 b = 2 Enter a,b: rc = 0 a = 3 b = 2 Enter a,b: rc = 0 a = 3 b = 2 Enter a,b: rc = 0 a = 3 b = 2 Enter a,b: rc = 0 a = 3 b = 2 avp@avp-xub11:~/hashcode$ gcc ac avp@avp-xub11:~/hashcode$ ./a.out Enter a,b: 1 2 rc = 2 a = 1 b = 2 Enter a,b: 3 a rc = 1 a = 3 b = 2 Input error rc = 1 skip 2 characters Try again Enter a,b: 3 4 rc = 2 a = 3 b = 4 Enter a,b: 5 6f rc = 2 a = 5 b = 6 Enter a,b: rc = 0 a = 5 b = 6 Input error rc = 0 skip 2 characters Try again Enter a,b: 5 6 rc = 2 a = 5 b = 6 Enter a,b: rc = -1 a = 5 b = 6 avp@avp-xub11:~/hashcode$ 

    rc = -1 at the end, this is a seal for EOF (^ D in * nix, ^ Z in Windows).

    Successes.

    UPD 2

    Slightly corrected skip() to work more correctly when typing from the keyboard.

    • Sorry, I just started learning programming, and I didn’t understand exactly what it means, see man 3 scanf. and how to program error handling correctly, I still don’t know how, or rather haven’t even reached it yet. - Stee1House
    • @steelhouse, judging by the comment you are trained in Windows. I advise to go to Linux, it will be easier. In any case, in Google, you can type the man function and read the links. - On the subject of the question: I think in the near future I will add an answer by example. - avp
    • Thank you very much, I am corrupting, at the expense of changing the OS, for now, I think, I just put ubuntu 12 and turned out to be a bit uncomfortable .. I will try to install on the virtual one, see how much better it is. - Stee1House
    • 2
      Better put Xubuntu or Mint. The Unity graphical environment, which by default stands in simple ubunt, is also very uncomfortable in my opinion. And the rest of the system is very good, especially for beginners. - skegg