71

%cC の printf フォーマット文字列にとの両方があるのはなぜ%sですか?

%cが単一の文字を表し、null で終わる文字列を表すことは知ってい%sますが、文字列表現だけでは十分ではないでしょうか?

4

11 に答える 11

99

おそらく、nullで終了する文字列と文字を区別するためです。があった場合は%s、すべての文字もnullで終了する必要があります。

char c = 'a';

上記の場合、cnullで終了する必要があります。これは私の仮定ですが:)

于 2012-06-01T07:22:18.027 に答える
74

%s0a (または'\0'、同じこと)に達するまで文字を出力します。

を持っているだけの場合char x;printf("%s", &x);-を期待しているので、アドレスを提供する必要%schar*&x + 1があります0

そのため、null で終了しない限り、単一の文字を印刷することはできません (非常に非効率的です)。

EDIT:他の人が指摘したように、2つはvar argsパラメーターで異なるものを期待しています.1つはポインター、もう1つは単一のcharです。しかし、その違いはやや明確です。

于 2012-06-01T07:19:27.693 に答える
38

単一の文字をnullで終了する必要があると他の人が言及している問題は、実際の問題ではありません。これは、フォーマットに精度を提供することで対処できます%.1s

私の見解でより重要なのは、%sその形式のいずれにおいても、1つまたは複数の文字へのポインターを提供する必要があるということです。つまり、右辺値(計算された式、関数の戻り値など)を出力したり、変数を登録したりすることはできません。

編集:私はこの答えに対する反応に本当に腹を立てているので、おそらくこれを削除します、これは本当に価値がありません。質問を読んだり、質問の専門性を理解する方法を知らなくても、人々はこれに反応するようです。

%.1sそれを明確にするために:私はあなたがよりも好むべきだとは言いません%c。私は、それで置き換えることができない理由%cは、他の答えが言うふりとは異なると言うだけです。これらの他の答えは技術的に間違っています。ヌル終了は。の問題ではありません%s

于 2012-06-01T07:34:47.017 に答える
14

%snull が見つかるまですべての文字を出力します (変数をポインターとして扱います)。

%c1文字だけ出力する(変数を文字コードとして扱う)

%s文字がポインターのように扱われるため、文字の使用は機能しません。ヌルが見つかるまで、メモリ内のその場所に続くすべての文字を出力しようとします。

他の回答から盗んで、別の方法で説明します。

を使用して文字を出力したい場合は%s、次のようにして char のアドレスを適切に渡し、null が見つかるまで画面にゴミが書き込まれないようにすることができます。

char c = 'c';
printf('%.1s', &c);
于 2012-06-01T07:20:03.610 に答える
7

の場合%s、値ではなく文字列のアドレスを指定する必要があります。

について%cは、文字の値を提供します。

%sの代わりに使用した場合、文字%cの後にどのようにアフターを提供し'\0'ますか?

于 2012-06-01T07:22:14.373 に答える
5

この楽しい質問に別の観点を追加したいと思います。

実際、これはデータの型付けに帰着します。ここで、文字へのポインターを提供し、

"%.1s"

これは確かに真実かもしれません。しかし、その答えは、C 設計者がプログラマーに柔軟性を提供しようとしていることにあります。実際、アプリケーションのフットプリントを減らす (小さいながらも) 方法です。

プログラマーは、一連の if-else ステートメントまたは switch-case を実行したい場合があります。この場合、状態に基づいて単純に文字を出力する必要があります。このため、単一の文字は 8 ビットであるのに対し、ポインタは 32 ビットまたは 64 ビット (64 ビット コンピュータの場合) であるため、文字をハード コーディングするとメモリ内の実際のスペースが少なくて済みます。ポインタは、メモリ内でより多くのスペースを占有します。

実際の char と char へのポインターを使用してサイズを小さくしたい場合は、printf 型の演算子内でこれを行う方法が 2 つあります。1 つは .1 をキーオフすることですが、char へのポインターまたは文字列 (char の配列) へのポインターではなく、本当に char 型を提供していることをルーチンが確実に知るにはどうすればよいでしょうか? これが、異なるため、「%c」を使用した理由です。

楽しい質問:-)

于 2012-06-01T18:02:49.737 に答える
2

とで実験をprintf("%.1s", &c)行いprintf("%c", c)ました。以下のコードを使用してテストし、bashのtimeユーティリティで実行時間を取得しました。

    #include<stdio.h>
    int main(){
        char c = 'a';
        int i;
        for(i = 0; i < 40000000; i++){
            //printf("%.1s", &c); get a result of 4.3s
            //printf("%c", c); get a result of 0.67s
        }
        return 0;
    }

結果は、使用%cがの10倍速いことを示してい%.1sます。したがって、%sは%cの役割を果たしますが、パフォーマンスには%cが必要です。

于 2012-06-06T16:47:03.873 に答える
2

C には、さまざまな型を処理するため、%cand%s形式指定子があります。

Acharとひもは、Night と 1 と同じくらい違います。

于 2012-06-01T14:00:07.073 に答える
2

%c は、整数である char を想定し、エンコード規則に従って出力します。

%s は、char値を含むメモリの場所へのポインタを期待し、0 (ヌル) 文字が見つかるまで、エンコード規則に従ってその場所に文字を出力します。

内部的には、2 つのケースは似ているように見えますが、1 つは値を処理し、もう 1 つはポインタを処理するため、あまり共通点はありません。1 つは特定の整数値を ascii char として解釈するための命令であり、もう 1 つはメモリ位置 char の内容を char ごとに反復し、値がゼロになるまでそれらを解釈することです。

于 2012-06-05T19:08:19.707 に答える
1

誰も何の参照も答えていないので、IBMのフォーマット定義に似たpubs.opengroup.comの printf 仕様を次に示します。

%c

int 引数は unsigned char に変換され、結果のバイトが書き込まれます。

%s

引数は、char の配列へのポインターでなければなりません。配列からのバイトは、終端のヌル バイトまで (ただし、ヌル バイトを含まない) 書き込まれます。精度が指定されている場合、そのバイト数を超えて書き込まれることはありません。精度が指定されていないか、配列のサイズよりも大きい場合、アプリケーションは配列にヌル バイトが含まれていることを確認する必要があります。

于 2012-06-05T18:42:51.790 に答える