1

私は Objective-C に不慣れで、インタラクティブなプログラムはこれが初めてです。私は今、約2週間学んでいます。

したがって、私の質問は次のとおりです。通常、複数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;
}
4

3 に答える 3

2

他のユーザーはすでにそれについてすべてを言っています。scanf は、次の scanf に渡されるバッファに新しい行 "\n" を自動的に挿入します。これは、書き込まれていないデータが次のストリームに書き込まれるためです。

ストリーム バッファをクリアするために使用できることを追加したいと思いfflushます。この場合は、

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

stdinごとに(コンソール入力)のバッファをクリアしますscanf

編集:それは知りませんでしたが、@Peter Kowalskiが言ったように、入力ストリームの動作が未定義であるため、入力ストリームにfflush(stdin)を使用することは避ける必要があります。

Cprograming.com FAQ > fflush(stdin) が間違っている理由

しかし、C で入力ストリームをフラッシュする保証された方法はないようです。

Cprograming.com FAQ > 入力ストリームをフラッシュする

C++ ではcin.ignore()afterを使用するのが標準的な方法であることは知っていますが、Ccin >> selectionでこれを行う方法がわかりませんfflush(stdin)

于 2012-08-19T06:30:27.913 に答える
0

NSLog* [注:Objective-Cを使用する場合は、Cocoa( )とstdio()を混在させるのではなく、Cocoaの入力変換メソッドを使用することをお勧めしますscanf。しかし、それはあなたの質問に答えません...]

整数、浮動小数点数、さらには文字列を解析する場合、scanf空白(スペース、タブ、行末など)をスキップし、すべての入力行は少なくとも行末で終了します(キャリッジリターン、ラインフィード、またはその両方の場合があります)。システム)。これは、最初の整数を読み取った後でも、少なくとも入力に行末があり、文字を読み取ろうとするとそれが返されることを意味します。したがって、入力を待つ必要はありません。残りの未使用の入力を破棄するには、を使用できますfpurge。例えば:

#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

于 2012-08-19T18:55:07.710 に答える
0

おそらく、アカウント所有者の名前を複数の文字にしたいのですが、その中の1文字しか読んでいませんscanf。そこに複数の文字を入力しようとしている場合scanf、最初の文字は最初の文字を読み取り、入力バッファーにはさらに多くの文字があるため、次の文字はscanf数値入力を待たずにすぐに読み取ろうとします。所有者名に 1 文字しか使用していない場合、入力バッファーから改行を使用する必要があります。

文字列をアカウント所有者名として読みたい場合は、複数の文字にスペースを割り当て、フォーマット文字列として%sではなく使用する必要があります。の戻り値も忘れずに確認してください。この関数は、正常にスキャンされたアイテムの数を返します。通常、無効な入力が原因でアイテムがスキャンされなかった場合は 0 を返すか、または を返します。%cscanfscanfEOF

char accountOwner[26];

// ...

// note that you can specify a width (max length) for a string using scanf
scanfReturn = scanf("%25s", accountOwner);
于 2012-08-19T05:48:59.683 に答える