-1
#include<stdio.h>
    int main(void)
    {
        int num;
        int days;
        int week;
        printf("enter a day\n");
        scanf_s("%d\n", &num);
        
    
        while (num)
        {
            week = num / 7;
            days = num - week * 7;
            printf("%ddays are %dweeks, %days\n", num, week, days);
        
        }
    
        if (num <= 0)
    
            printf("your input is wrong\n");
        else
            printf("enter your day again\n");
            
        
            return 0;
    }

   

how can let printf("%ddays are %dweeks, %days\n", num, week, days) only come once then show printf("enter your day again\n"); if my input >0

aster dis
  • 13
  • 6
  • 3
    If you want it to print only once, move it outside the loop. What exactly are you trying to do? – William Pursell Sep 26 '22 at 22:21
  • 2
    If `num != 0`, you have an infinite loop. It would seem you intend to be updating `num` in the loop, but have forgotten to do so. – William Pursell Sep 26 '22 at 22:22
  • i trying to allow the user to repeatedly enter day values; terminate the loop when the user enters a nonpositive value like <=0 – aster dis Sep 26 '22 at 22:23
  • 1
    @asterdis: If you want the user to be able to repeatedly enter input, then you should move the `scanf_s` function call into the loop. – Andreas Wenzel Sep 26 '22 at 22:26
  • @AndreasWenzel like that while (scanf_s("%d\n", &num))? – aster dis Sep 26 '22 at 22:28
  • @AndreasWenzel yeah is working right now, but it doesn't allow me to input again – aster dis Sep 26 '22 at 22:30
  • @asterdis: No, the return value of `scanf` will indicate the number of matched arguments (either `0` or `1`) in this case, but not the value of the converted arguments. I will write a proper answer for you to explain it. – Andreas Wenzel Sep 26 '22 at 22:31
  • should i also do else (scanf_s("%d\n", &num)) like that? – aster dis Sep 26 '22 at 22:31
  • In your question, you state that the loop should "terminate" when the user enters a non-positive value. However, in your posted code, you seem to be attempting to tell the user to "try again", which implies that you do not want the loop to terminate in this case, but rather want the loop to restart. Please clarify this contradiction. Should the program terminate with an error message if the user enters a non-positive value? Or should the user be reprompted for input? – Andreas Wenzel Sep 26 '22 at 22:36
  • i want if user input is >=0 then stop the program – aster dis Sep 26 '22 at 23:17
  • @asterdis: Ok, I will rewrite my answer so that it will stop the program if the input is valid. – Andreas Wenzel Sep 26 '22 at 23:18
  • @asterdis: I have now finished rewriting my answer, and have also added lots of additional information on how to prevent the program from misbehaving if the user enters non-digit input. – Andreas Wenzel Sep 26 '22 at 23:32
  • @asterdis Note: `scanf_s("%d", &num)` returns 3 different values: `EOF, 0, 1`. – chux - Reinstate Monica Sep 26 '22 at 23:57
  • @AndreasWenzelA Sir i run your program it can't into a loop. for example, if i put an invalid number doesn't allow me enter again even i put valid number – aster dis Sep 27 '22 at 00:08
  • @asterdis: If you want to discuss my answer, then please post a comment to my answer instead of a comment to your question. Also, please tell me the exact input that you are entering. Additionally. please tell me what you mean by "your program", because I have posted two programs in my answer. It is unclear which one you are referring to. – Andreas Wenzel Sep 27 '22 at 00:13

1 Answers1

1

First of all, it is generally not recommended to use the function scanf_s if you want your code to be portable to other platforms. It is usually better to use scanf. If the only reason you are using scanf_s instead is because the Microsoft compiler is telling you that you must do so, then I suggest that you add the line

#define _CRT_SECURE_NO_WARNINGS

to the very top of your source code file and the Microsoft compiler will accept that you use scanf instead.

Also, the line

scanf_s("%d\n", &num);

is wrong. You should remove the \n from the format string. See this question for more information:

What is the effect of trailing white space in a scanf() format string?

If you want your program to continue reprompting the user until the input is valid, then you can use the following code:

#include <stdio.h>

int main( void )
{
    for (;;) //infinite loop, equivalent to while(1)
    {
        int num;
        int days;
        int week;

        //get input from user and verify it
        printf( "Enter number of days: " );
        if (
            scanf( "%d", &num ) != 1
            ||
            num <= 0
        )
        {
            printf( "Invalid input! Please try again.\n" );
            continue;
        }

        //calculate number of weeks and days
        week = num / 7;
        days = num % 7;

        //print result
        printf( "%d days are %d weeks, %d days.\n", num, week, days );

        //break out of infinite loop
        break;
    }
}

This program has the following behavior:

Enter number of days: 8
8 days are 1 weeks, 1 days.
Enter number of days: -3
Invalid input! Please try again.
Enter number of days: 0
Invalid input! Please try again.
Enter number of days: 14
14 days are 2 weeks, 0 days.

However, it is worth noting that this program will get stuck in an infinite loop if the user enters anything else except digits:

Enter number of days: abc
Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
Enter number of days: Invalid input! Please try again.
[...]

This is because scanf will immediately fail without consuming the invalid input, so that the next call to scanf will fail for exactly the same reason.

The function scanf behaves this way, because it is not designed for user-based line input. Therefore, it would be better to not use this function. It would be better to use the function fgets to always read a whole line of input as a string, and then to use the function strtol to attempt to convert this input to an integer.

In this answer of mine to another question, I created a function get_int_from_user which uses fgets and strtol instead of scanf so that it does not have the problem mentioned above. This function will perform extensive input validation and automatically reprompt the user if the input is not a valid integer or cannot be converted to an int for some other reason.

If I rewrite your program to use this function, it will look like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>

//declare function prototype
int get_int_from_user( const char *prompt );

int main( void )
{
    for (;;) //infinite loop, equivalent to while(1)
    {
        int num;
        int days;
        int week;

        //read integer from user
        num = get_int_from_user( "Enter number of days: " );

        //verify that number is positive
        if ( num <= 0 )
        {
            printf( "Invalid input! Please try again.\n" );
            continue;
        }

        //calculate number of weeks and days
        week = num / 7;
        days = num % 7;

        //print result
        printf( "%d days are %d weeks, %d days.\n", num, week, days );

        //break out of infinite loop
        break;
    }
}

int get_int_from_user( const char *prompt )
{
    //loop forever until user enters a valid number
    for (;;)
    {
        char buffer[1024], *p;
        long l;

        //prompt user for input
        fputs( prompt, stdout );

        //get one line of input from input stream
        if ( fgets( buffer, sizeof buffer, stdin ) == NULL )
        {
            fprintf( stderr, "Unrecoverable input error!\n" );
            exit( EXIT_FAILURE );
        }

        //make sure that entire line was read in (i.e. that
        //the buffer was not too small)
        if ( strchr( buffer, '\n' ) == NULL && !feof( stdin ) )
        {
            int c;

            printf( "Line input was too long!\n" );

            //discard remainder of line
            do
            {
                c = getchar();

                if ( c == EOF )
                {
                    fprintf( stderr, "Unrecoverable error reading from input!\n" );
                    exit( EXIT_FAILURE );
                }

            } while ( c != '\n' );

            continue;
        }

        //attempt to convert string to number
        errno = 0;
        l = strtol( buffer, &p, 10 );
        if ( p == buffer )
        {
            printf( "Error converting string to number!\n" );
            continue;
        }

        //make sure that number is representable as an "int"
        if ( errno == ERANGE || l < INT_MIN || l > INT_MAX )
        {
            printf( "Number out of range error!\n" );
            continue;
        }

        //make sure that remainder of line contains only whitespace,
        //so that input such as "6sdfj23jlj" gets rejected
        for ( ; *p != '\0'; p++ )
        {
            if ( !isspace( (unsigned char)*p ) )
            {
                printf( "Unexpected input encountered!\n" );

                //cannot use `continue` here, because that would go to
                //the next iteration of the innermost loop, but we
                //want to go to the next iteration of the outer loop
                goto continue_outer_loop;
            }
        }

        return l;

    continue_outer_loop:
        continue;
    }
}

As you can see, the program no longer gets stuck in an infinite loop if I enter something else than digits:

Enter number of days: abc
Error converting string to number!
Enter number of days: 8abc
Unexpected input encountered!
Enter number of days: 8
8 days are 1 weeks, 1 days.
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
  • @chux: My function `get_int_from_user` treats an end-of-file event the same way as a newline character. See the following line: `if ( strchr( buffer, '\n' ) == NULL && !feof( stdin ) )`. Therefore, it should work in the situation that you describe. – Andreas Wenzel Sep 27 '22 at 00:05
  • enter a day 0 0days are 0weeks, 0ays your input is wrong C:\Users\86377\source\repos\assignment2\x64\Debug\item3.exe (process 10244) exited with code 0. To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops. Press any key to close this window . . . – aster dis Sep 27 '22 at 00:26
  • the program i run is the first one – aster dis Sep 27 '22 at 00:27
  • @asterdis: Please specify the desired output as well as the actual output. It is unclear whether the output you are specifying is the desired output or the actual output. – Andreas Wenzel Sep 27 '22 at 00:29
  • `scanf_s` is C11, but it is _optional_. Good readings on this are: “[scanf_s is not included in C11](https://stackoverflow.com/questions/65471315/scanf-s-is-not-included-in-c11)” and “[Why didn't gcc (or glibc) implement _s functions?](https://stackoverflow.com/questions/50724726/why-didnt-gcc-or-glibc-implement-s-functions)”. – Dúthomhas Sep 27 '22 at 00:30
  • @ Andreas Wenzel is the actual output – aster dis Sep 27 '22 at 00:36
  • @asterdis: When I enter `0` into the first program I posted in my answer, I get the output `"Invalid input! Please try again."`. Is that not what you want? If you are getting different output, then please verify that you are actually running my posted code and not something else. – Andreas Wenzel Sep 27 '22 at 00:40
  • @Andreas Wenzel I check again is the same as your code but still doesn't let me input it again after I enter the first time – aster dis Sep 27 '22 at 00:48
  • @asterdis: Are you using my posted code exactly as-is? Or did you make modifications to it, for example by changing `scanf` to scanf_s` or by adding `#define _CRT_SECURE_NO_WARNINGS`? – Andreas Wenzel Sep 27 '22 at 00:50
  • @asterdis: Are you able to reproduce the error using [this online interface](https://www.onlinegdb.com/n26Dj60VB)? On that interface, when I press the "Run" button, the code works perfectly, as far as I can tell. – Andreas Wenzel Sep 27 '22 at 00:53
  • @AndreasWenzel yes, I didn't make any modifications. – aster dis Sep 27 '22 at 00:53
  • I suspect that you are not running the code that you think you are running. If you change the line `printf( "Enter number of days: " );` to `printf( "Enter numXXber of days: " );`, does the output of your program change accordingly? Does it print `"Enter number of days: "` or `"Enter numXXber of days: "`? If the output does not change, then my suspicion is correct. – Andreas Wenzel Sep 27 '22 at 00:54
  • oh, yeah, but i already save it – aster dis Sep 27 '22 at 00:58
  • @asterdis: Please answer my question, if you want me to help you. Does the output change to `"numXXber`" or does it stay `"number"`? – Andreas Wenzel Sep 27 '22 at 01:00
  • no change stay number – aster dis Sep 27 '22 at 01:02
  • @asterdis: If changing the `printf` statement of your program does not change the actual output of your program, then you are not running the code that you think you are. Therefore, you are probably using your compiler/[IDE](https://en.wikipedia.org/wiki/Integrated_development_environment) incorrectly. I suggest that you read the output of your compiler closely, in order to determine whether it is printing any error messages. Which compiler/IDE are you using? – Andreas Wenzel Sep 27 '22 at 01:05
  • @AndreasWenzel [True, true](https://www.youtube.com/watch?v=hRtB5B6grnA). – chux - Reinstate Monica Sep 27 '22 at 02:25