2013-10-02 19 views
6

は、私は、文字列と長さが含まれている構造体を持っています。しかし、私はprintfのような関数を使ってこの構造体の内容を出力できるようにしたい。 dataはヌルターミネーターを持っていないかもしれません(または間違った場所に持っているかもしれません)ので、ただ%sを使うことはできません。しかし、%.*s指定子にはがありますが、intが必要です。のprintf可変文字列の長さ指定

ここで質問はprintfを使用して文字列を出力できますか?

+7

値が適合すれば 'size_t'を' int'に変換することができます。 –

+3

@KerrekSB長さが興味深い 'printf'になる' int'に収まらない場合はcall :-))オーバーフローする可能性があるので、チェックする必要があります。 – cnicutar

+6

'data'に印字不可能な文字(ヌル文字など)が含まれている場合、'%s'はまったく必要ありません。ループを作成します。 –

答えて

3

簡単な解決策だけで使用することです未フォーマット出力:

fwrite(x.data, 1, x.len, stdout); 

、それがループ内で使用する必要がありますのでfwriteは、すべてのものを記述しない場合があるのでこれは、実際に悪い形です。

for (size_t i, remaining = x.len; 
    remaining > 0 && (i = fwrite(x.data, 1, remaining, stdout)) > 0; 
    remaining -= i) { 
} 

x.lenSIZE_T_MAXよりも大きくないことを確認してください。

+0

+1はこれを自分自身で削除しようとしていました。はるかに簡単にするのは難しいです。 – WhozCraig

+0

しかしsnprintfのようなものを使いたければ、これはうまくいきません。その場合、私はデータをコピーすることができますが、私はむしろ他のフォーマット指定子( '%i 'のようなもの)を使うことができます。 –

+0

@drderp:分かりません。あなたは 'snprintf'をどのように使っていますか?あなたはファイルではなくメモリの場所に書き込むために 'memcpy'を使うことができます... –

1

printfを使用して文字列を出力するにはどうすればよいですか?

1回のコールで?あなたは、あなたが奇妙な場所にヌルターミネーターを持っているかもしれないと言っているので、意味のある方法ではできません。一般に、バッファに印刷できない文字が含まれている場合は、文字列を出力するときに、その文字をどのように印刷するかを指定する必要があります。あなたのロジックが指示するように、ループを作成し、各文字をテストし、それを印刷する(または印刷しない)。

11

あなたの文字列がその中に埋め込まれたNUL文字を持っていないと仮定すると、あなたは、鋳造後%.*s指定子を使用することができますsize_tintに:

string_t *s = ...; 
printf("The string is: %.*s\n", (int)s->len, s->data); 

はまたあなたの文字列の長さが未満であると仮定だとINT_MAX。文字列の長さがINT_MAXより大きい場合は、他の問題があります(2つの文字をプリントアウトするのにかなりの時間がかかります)。

+0

そうは思わないかもしれませんが、OP *は16ビットのint型埋め込みデバイスまたは歴史的デバイスをターゲットにすることができます – user4815162342

+0

これは本当にこれを行う最善の方法ですか?私が最初にこの振る舞いに気づいたとき、私の最初の質問は「なぜ、それはとにかく「size_t」ではないのですか?」 –

+0

@JeremyRodi:確かに分かりませんが、 'size_t'の代わりに' int'を使うのは、 'size_t'型が存在する前であっても、C言語が標準化される前に書かれたコードと下位互換性があるからです。 –

関連する問題