scanf是不是在循环中等待输入?

时间:2012-08-19 05:46:33

标签: objective-c c scanf foundation

我是Objective-C的新手,这是我的第一个交互式程序。我现在已经学习了大约两个星期。

所以,我的问题是:通常我注意到当你连续多个scanf时,他们每个人都在等待输入 - 但是在这种情况下,我要求帐户所有者名称和余额 - 它会触发NSLog个函数,而不是等待第一次输入。

这是我的主要内容:

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's 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;
}

3 个答案:

答案 0 :(得分:2)

其他用户已经说了一切。 scanf在传递给下一个scanf的缓冲区中自动插入一个新行“\ n”。这是因为任何未写入的数据都写在下一个流中。

我想补充一点,您可以使用fflush清除流缓冲区,在这种情况下您要使用

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

在每stdin之后清除scanf(控制台输入)的缓冲区。

编辑:我不知道,但正如@Peter Kowalski所说,应该避免使用fflush(stdin)作为输入流,因为它对输入流有一个未定义的行为。

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

但似乎没有一种保证方法可以在C中刷新输入流。

Cprograming.com FAQ > Flush the input stream

我知道在C ++中,标准方法是在cin.ignore()之后使用cin >> selection,但我不知道如何在C中完成此操作。也许一些更有经验的用户可以对某些内容有所了解发生在fflush(stdin)

答案 1 :(得分:0)

据推测,您希望帐户所有者名称不只是一个字符,但您只需阅读scanf中的单个字符。如果您尝试在那里输入多个字符,则第一个scanf将读取第一个字符,并且由于输入缓冲区中有更多字符,下一个scanf将立即尝试读取而无需等待为您的数字输入。如果 仅使用单个字符作为所有者名称,那么您将需要使用输入缓冲区中的换行符。

如果您想要读取字符串作为帐户所有者名称,则需要为多个字符分配空间,并使用%s而不是%c作为scanf格式字符串。另请记得检查scanf的返回值。该函数将返回成功扫描的项目数,如果没有扫描项目则返回0,通常是由于输入无效,或返回EOF

char accountOwner[26];

// ...

// note that you can specify a width (max length) for a string using scanf
scanfReturn = scanf("%25s", accountOwner);

答案 2 :(得分:0)

* [注意:如果您打算使用Objective-C,您可能希望使用Cocoa的输入转换方法而不是混合Cocoa(NSLog)和stdio(scanf)。但这不能回答你的问题...]

解析整数时,浮点数甚至字符串scanf都会跳过空格 - 例如空格,制表符,行尾等 - 并且每个输入行至少以行尾结束(可以是回车符,换行符或两者,具体取决于系统)。这意味着在读完第一个整数后,输入中至少仍有一行结束,并且尝试读取一个字符将返回它 - 因此无需等待输入。要丢弃剩余的未使用的输入,您可以使用fpurge。 E.g:

#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);
    }
}

请注意,读取字符串确实会跳过空格,因此如果您的帐户所有者是字符串,则不需要fpurge