How exactly does space work with scanf?

I am a math teacher and I am learning the very basics of C programming. I need a program to read input, consisting of an array whose components must have certain details; I would like the program to ask the user for the array components. Then the user needs to enter such components, separating them with spaces. Details are not important to get the main question; I will choose a simpler example than the one I'm dealing with: let me want the array with 6 components to not contain the number 4. So I tried:

#include <stdio.h> int main(void) { int a[6]; printf("enter components: "); int i; for (i = 0; i < 6; i++) { scanf("%d", &a[i]); if (a[i] == 4) printf(" \n\n4 is not allowed, try again\n\n"); } for (i = 0; i < 6; i++) { printf("%d ", a[i]); } } 

If I compile this and run it and, for example, type:

 1 2 3 4 5 6 

I will get my error message, but only after pressing enter, that is, after entering all six components (not immediately after you press the space bar for the fourth time). So here are my questions (I'm looking for solutions that don't use strings or pointers if it is impossible to do without them):

  • Is there a way to make the program read the component (and act accordingly) immediately after its subsequent space has been introduced? I suppose not, because scanf only works after the user presses enter, not a space, right?

  • If this does not happen, is there a way to get the program to read the components immediately after pressing input at the end, but let the user pick up the last component? For example, with the above input, I would like the program to display something like this:

     4 is not allowed 1 2 3 _ 

    so that the user can correct his entry (possibly also changing the first three digits).

Sorry if this question is too dumb! Thank you for your help!


EDIT: Well, thanks for the great answers, you were all very helpful! I wish I could take more than one.

+4
source share
5 answers

See the following code:

 #include <stdio.h> int main(void) { int a[6]; int i; bool hasError = false; int errorIndex = 0; do{ hasError = false; printf("enter components: "); for (i = 0; i < errorIndex; i++) printf("%d ", a[i]); for (i = errorIndex; i < 6; i++) { scanf("%d", &a[i]); if (a[i] == 4 && hasError == false){ printf(" \n\n4 is not allowed, try again\n\n"); hasError = true; errorIndex = i; } } }while(hasError == true); for (i = 0; i < 6; i++) { printf("%d ", a[i]); } } 
+1
source

In the for loop, after each iteration, the counter automatically adds one at a time. If you get invalid input, you must prevent the counter from increasing. To do this, just add i--; to your code when you give the wrong input.

 #include <stdio.h> int main(void) { int a[6]; printf("enter components: "); int i; for (i = 0; i < 6; i++) { scanf("%d", &a[i]); if (a[i] == 4){ printf(" \n\n4 is not allowed, try again\n\n"); i--; } } for (i = 0; i < 6; i++) { printf("%d ", a[i]); } } 
+2
source

This is because your terminal is in "cooked" mode. Characters are not even sent to the program until the user presses the enter button.

+1
source

The improvement at Peace Milad Hosseini responds (I mistakenly defined it as an uncontrolled infinite loop ... in fact, this is exactly the infinite loop that I describe in my comment) ...

I would write a small function that has either a “white list” (things you want) or a “black list” that you don’t want, and check each value to see if it belongs to or not (depending on the approach) to the list. This way you can keep a separate place where values ​​that you are ready to accept or values ​​that you are not are stored, so your main function does not get really messy with exceptions or inclusions in the "if"

so your code will be

 if(isAllowed(a[i]){ myList[j] = a[i]; //j is your alternate counter } 
+1
source

You can do something like this:

 int i,a[6]; for (int i=0;i<6;i++) { scan: scanf("%d",&a[i]); } for (int i=0;i<6;i++) if (a[i]==4) { printf("4 is not allowed. re-enter the last %d numbers\n",6-i); goto scan; } 

Please note that in most cases it is better to avoid using goto , but in this case I think it is natural.

If you really want this, you can print the first i numbers (before goto ), but it was complicated (and platform dependent) so that the user could change these numbers.

+1
source

Source: https://habr.com/ru/post/1392261/


All Articles