3

私はゆっくりと C を学んでいます。文字列を扱う入力と出力に関するこのページを読みました: http://www.cprogramming.com/tutorial/c/lesson9.html

最後のコード例でfgetsは、変数への入力を取得して char 配列に割り当てるために使用されますname。私は自分のプログラムに似たようなものを実装しようとしました。

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

/* This is my very first C program! */

bool test=true;

/* Function Prototypes */

int mult(int x, int y);

/* Structures */

struct Person {
    int age;
    char name[256];
};

/* Complicated Array ;P */

struct Person *FirstPeriod[22];
char FakeString[100];

void PracticeStrings()
{
    int i;
    fgets(FirstPeriod[0]->name, 256, stdin);
    for (i=0;i<256;i++)
    {
            if (FirstPeriod[0]->name[i]=='\n')
                FirstPeriod[0]->name[i]='\0';
    }
    printf("\n\nHello Student 0: %s",FirstPeriod[0]->name);
}

int main()
{
    struct Person DadeLamkins;
    DadeLamkins.age=16;
    int numb;
    int x;
    int *numb_address=&numb;
    numb_address=malloc(sizeof(*numb_address));

    FirstPeriod[0]=&DadeLamkins;

    if (true)
        printf("-__- \n\n");

    printf("Please enter a number: ");
    scanf("%d", &numb);
    switch (numb) {
        case 0:
            printf("Dude, 0 is lame...\n");
            break;
        case 7:
            printf("Dude, 7 is my favorite number!\n");
            break;
        default:
            printf("You entered %d\n", numb);
            break;
    }
    for (x=0;x<numb+1;x++) {
        printf("\n::# %d",mult(x,2));
    }
    printf("\n\n%d",numb_address);
    free(numb_address);
    numb_address=0;
    PracticeStrings();
    getchar();
    return 0;
}

int mult (int x, int y)
{
    return x*y;
}

26行目のPracticeStrings関数が現在の問題です。コンパイルするとHello Student 0: 、入力を受け入れる前に表示されます(からfgets)。Code::Blocks を使用してコンパイルしています。

どんな助けでも大歓迎です!

編集...

ははは、はい、私のプログラムが非効率的で非常にばかげていることは理解しています。お察しのとおり、実際にはあまり効果がありません。ほとんどの場合、コード例を実際に書き直すことなく、現在学んでいることを押し付けて適用しようとするものです (一語一句コピーすると何を学べますか?)。とにかく、助けてくれてありがとう!それは一理あると思います!私のチュートリアルがそれについて言及していないのは残念です。それは、もう少し高度な理解が必要なものだと確信しています。チュートリアルの作成者は、私が行ったように関数を混在させる人がいるとは思っていなかったに違いありません。

たくさんの人に感謝します!うまくいけば、私はこれに慣れることができます。私は多くのスクリプトを作成し、.net 言語で多くの作業を行ってきました。Cこのリストに追加できることを願っています :)

4

2 に答える 2

4

数字を読むと、次のようになります。

scanf("%d", &numb);

stdinまだ\nバッファに残っています。したがって、電話PracticeStrings()をかけた後:

fgets(FirstPeriod[0]->name, 256, stdin);

あなたは読ん\nで、

FirstPeriod[0]->name[i] == '\0';

さらに、あなたが学んでいるように、検証することを学びましょう:)

すなわち:

if ((foo = malloc(blah)) == NULL) {
    ... err ...

さらに重要なこと:

if (scanf(..) != number_of_items_i_want) {
    ... did not get a number, or what ever I wanted ...

于 2012-04-10T00:06:50.273 に答える
0

あなたの問題は、コンソールの動作とscanf()呼び出しによるものだと思います。

コンソールのデフォルト設定は、おそらく行バッファリングです。つまり、端末で入力したものは、エンター キーを押すまで stdin に送信されません。

scanf()ただし、 (in )への呼び出しmain()は、末尾の改行ではなく、入力した整数を取得するだけです。キャリッジ リターンは、26 行目の呼び出しまで、stdin に未読のままです。fgets()これを回避する 1 つの方法は、scanf() を取得して、末尾のキャリッジ リターンも消費することです。

scanf("%d%*c", &numb);
stdin から に整数を読み取り&numb、余分な文字を読み取り (そして破棄) します。

scanf()これはすべて、予期しない文字列を取得した場合にどのように対処するかという、の使用に関する大きな問題の 1 つを浮き彫りにします。より安全な方法は、 と を組み合わせて使用​​することfgets()ですsscanf()。前者ではファイルから文字列を読み取ることができ (既に行ったように)、後者ではフォーマット文字列を実行できます。例えば。


    char temp[20];
    fgets(temp, 20, stdin);
    sscanf(temp, "%d", &numb);
于 2012-04-10T00:17:50.647 に答える