Scanf not waiting for input in my loop?

I am new to Objective-C, and this is really my first interactive program. I studied for about 2 weeks.

So my question is: I usually noticed when you have several scanf in a line, each of them is waiting for input - however, in this situation, when I ask for the account owner name and balance - it starts both NSLog instead of waiting for the first input.

Here is my main one:

 int main(int argc, char* argV[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; bank *columbiaBank = [[bank alloc] init]; int iteration = 0; while (true) { int selection = 0; NSLog(@"\n1. Add Account \n2. Remove Account \n3. Modify Account \nWhat would you like to do?:"); scanf("%i", &selection); if (selection == 1) { NSLog(@"\nEnter account owner:"); char accountOwner; scanf("%c", &accountOwner); NSLog(@"\nEnter opening balance:"); float openingBalance; scanf("%f", &openingBalance); // create and add new account bankAccount *newAccount = [[bankAccount alloc] initWithProps:[NSString stringWithFormat:@"%c", accountOwner] :[NSString stringWithFormat:@"%i", iteration] :openingBalance]; [columbiaBank addAccount:newAccount]; [newAccount release]; NSLog(@"\nAccount successfully added!"); } else if (selection == 2) { NSLog(@"\nEnter account id:"); int accountId; scanf("%i", &accountId); // remove account [columbiaBank removeAccount:[NSString stringWithFormat:@"%i", accountId]]; NSLog(@"\nAccount successfully removed!"); } else if (selection == 3) { NSLog(@"\nThe bank currently has %i accounts.", columbiaBank.totalAccounts); NSLog(@"\nThe bank current balance from all accounts is $%f", columbiaBank.totalBankBalance); NSLog(@"\n-- Output of all account info --"); [columbiaBank printAccounts]; } else { NSLog(@"You did not enter a valid action."); } iteration++; } [columbiaBank release]; [pool drain]; return false; } 
+1
source share
3 answers

* [Note: If you intend to use Objective-C, you can use input conversion methods from Cocoa, rather than mixing Cocoa ( NSLog ) and stdio ( scanf ). But this does not answer your question ...]

When analyzing integers, scanf floats and even scanf lines omit spaces - for example. spaces, tabs, end of line, etc. - and each line of input ends with at least the end of the line (which may be a carriage return, line feed, or both, depending on the system). This means that after reading your first integer, there is still at least the end of the line in the input, and trying to read the character will return it - therefore, do not wait for input. To undo the remaining, unused input, you can use fpurge . For instance:.

 #include <stdio.h> int main(int argc, char* argV[]) { int selection = 0; fputs("\n1. Add Account \n2. Remove Account \n3. Modify Account \nWhat would you like to do?: ", stdout); scanf("%i", &selection); if (selection == 1) { fputs("\nEnter account owner: ", stdout); fpurge(stdin); // skip any input left in the buffer as %c takes the very next character and does not skip whitespace char accountOwner; scanf("%c", &accountOwner); fputs("\nEnter opening balance: ", stdout); float openingBalance; scanf("%f", &openingBalance); printf("%c - %f\n", accountOwner, openingBalance); } } 

Please note that reading in character strings skips spaces, so if your account owner was a string, you do not need fpurge .

0
source

Other users have already told all this. Scanf inserts the new line "\ n" automatically into the buffer, which is passed to the next scanf. This is due to the fact that any unwritten data is recorded in the next stream.

I want to add that you can use fflush to flush the stream buffer, in which case you want to use

 scanf("%i", &selection); fflush(stdin) 

to clear the stdin buffer (console input) after each scanf .

Edit: I didnโ€™t know this, but as @Peter Kowalski said that using fflush (stdin) for an input stream should be avoided as it has undefined behavior for input streams.

Cprograming.com FAQ> Why is fflush (stdin) wrong.

But it seems that there is no guaranteed method for cleaning the input stream in C.

Cprograming.com Frequently Asked Questions> Clear Input Stream

I know that in C ++ the standard way is to use cin.ignore() after cin >> selection , but I donโ€™t know how this can be done in C. Perhaps a more experienced user can give some idea of โ€‹โ€‹what is happening with fflush(stdin) .

+2
source

Presumably you want the account owner name to be more than one character, but you only read one character in scanf . If you try to enter more than one character, the first scanf will read the first character, and since there is more in the input buffer, the next scanf will try to read immediately, without waiting for your numerical input, If you use only one character for the name of the owner, you will need to use a new line from the input buffer.

If you want to read the string as the name of the account owner, you need to allocate space for more than one character and use %s rather than %c as the scanf format string. Also remember to check the return value for scanf . The function will return the number of successfully checked items or 0 if no items were scanned, usually due to incorrect input or return of EOF .

 char accountOwner[26]; // ... // note that you can specify a width (max length) for a string using scanf scanfReturn = scanf("%25s", accountOwner); 
0
source

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


All Articles