2

以下のコードが次のように機能する理由が不思議です。変数「account_name」を初めて出力すると、正しく機能します。2 回目と 3 回目はまったく機能せず、代わりに意味不明な結果が出力されます。C初心者です。

const char * get_account_name(){

    char loc_account_name[255];

    printf ("Please enter the ledger Account name: ");
    scanf ("%[^\n]", &loc_account_name);
    fflush(stdin);
    printf ("\n");
    return ( loc_account_name );
}

void main (void)
{

    /* Declare variables. We use the predefined "MAX_ENTRIES" definition to define how large the arrays will be */

    float   credits[MAX_ENTRIES], debits [MAX_ENTRIES], starting_balance, ending_balance;
    int     debit_amount, credit_amount, x;
    char    * account_name;

    printf ("Welcome to the Sears Ledger System\n\n");

    /* Prompt the user to enter the name of the account, we allow for up to 255 characters and account for names with spaces as well */ 
    account_name = get_account_name();
    printf("%s",account_name);
    printf("%s",account_name);
    printf("%s",account_name);


} /* end main*/

*更新

get_account_name 関数の scanf のアンパサンドを削除しました。その後、正しい値が複数回出力されることがわかりましたが、その後プログラムは永久にハングします。残念ながら、私が使用せざるを得ないコンパイラにはデバッガがないため、何が起こっているのかまだ混乱しています。

char * get_account_name(){

    char * loc_account_name;
    printf ("Please enter the ledger Account name: ");
    scanf ("%[^\n]", loc_account_name);
    fflush(stdin);
    printf ("\n");

    return loc_account_name;

}

* *更新 2

char *get_account_name() {

    char loc_account_name[255];
    char *r;

    printf ("Please enter the ledger Account name: ");
    scanf ("%[^\n]", &loc_account_name);
    fflush(stdin);
    printf("%s\n", loc_account_name);

    *r = malloc(strlen(loc_account_name) + 1);
    strcpy(r, loc_account_name);
    return r;
}

void main (void)
{

    char     * account_name;

    /* Prompt the user to enter the name of the account, we allow for up to 255 characters and account for names with spaces as well */ 
    account_name = get_account_name();
    printf("%s\n", account_name);
    printf("%s\n", account_name);
    printf("%s\n", account_name);
    free(account_name);


} /* end main*/
4

2 に答える 2

4

loc_account_nameからローカル変数のアドレスを返していますget_account_name()。このメモリは、関数が戻った後は存在しません。(ええと、同じデータがまだ短時間含まれているように見えますが、2 回目または 3 回目はそうではありません。)

これを修正するには、次のいずれかを実行できます。

  • malloc()関数内の文字列に (使用または同様の方法で)スペースを割り当てget_account_name()、そのスペースへのポインターを返します。呼び出し元は、メモリを解放する責任があります。

    char *get_account_name() {
        char loc_account_name[255];
        // get user input into loc_account_name
        char *r = malloc(strlen(loc_account_name) + 1);
        strcpy(r, loc_account_name);
        return r;
    }
    
    account_name = get_account_name();
    // use account_name
    free(account_name);
    

    ランタイム ライブラリに / のいずれかがある場合は、 /strdup()の代わりに使用できることに注意してください。malloc()strcpy()

  • 呼び出し元に文字列の最大長にスペースを割り当ててもらい、そのバッファー (およびバッファー長) をget_account_name()関数に渡して入力させます。

    void get_account_name(char *buffer, int buffer_size) {
        // get user input into buffer
        // but make sure the user can't type more than buffer_size characters!
    }
    
    char account_name[255];
    get_account_name(account_name, sizeof(account_name));
    // use account_name
    

関数から文字列を返すことは、C では厄介で厄介です。これが、ほとんどの最新の言語 (C++ を含む) が文字列を処理するためのより優れた組み込み方法を備えている理由です。

于 2012-07-16T02:08:34.343 に答える
0

シングルスレッド環境では、次のような単純な静的バッファーを使用できます。

const char *get_account_name(void) {

    static char loc_account_name[255];
    int c;

    printf ("Please enter the ledger Account name: ");
    scanf ("%254[^\n]", loc_account_name);
    while( (c=getchar())!=EOF && c!='\n' );
    printf("%s\n", loc_account_name);

    return loc_account_name;
}

入力バッファをクリアするには、標準に準拠した方法を使用する必要があります。

于 2012-07-16T09:29:31.277 に答える