Cでの文字列パディング


80

StringPadRight( "Hello"、10、 "0")-> "Hello00000"を実行することになっているこの関数を作成しました。

それは機能しますが、いくつかの奇妙な副作用があります...他の変数のいくつかが変更されます。どうすればこれを修正できますか?

c  string  padding 

回答:


173

printfがパディングを行うことを知っておくと役立つ場合があります。フォーマット文字列として%-10sを使用すると、10文字の長さのフィールドに入力が正しくパディングされます。

出力します

この場合、-記号は「左揃え」を意味し、10は「フィールド内の10文字」を意味し、sは文字列を揃えていることを意味します。

Printfスタイルのフォーマットは多くの言語で利用可能であり、Web上に多くの参照があります。これは、フォーマットフラグを説明している多くのページの1つです。いつものように、WikiPediaのprintfページも役に立ちます(ほとんどの場合、printfがどれだけ広く普及したかについての歴史のレッスンです)。


4
文字列をスペース以外の別の文字で埋めたい場合はどうなりますか?これをCのprintfで行う方法はありますか?
Peter Ajtai 2011年

それが可能ではないようです。(グーグルをしました。また、のマニュアルページにprintfはそのような機能の表示がないようです。)
Victor Zamanian 2012

@ victor-cplusplus.com / reference / clibrary / cstdio / printf-「フラグ」セクションと「幅」セクションを参照してください。
トムレイズ2012

1
@ tom-はい、「結果は空白で埋められます」。ですから、それは不可能のようです。述べたように、同じ情報がマニュアルページで利用可能です。また、printf同じでないにしてもほとんど同じように動作するはずですが、これCであり、C ++ではありません。
ビクターザマニアン2012

1
@ビクター。申し訳ありませんが、ピーターのその後の質問ではなく、私の答えに返信していると思いました。はい、0で埋めるか、 ''で埋めることしか選択できません。
トムレイズ2012

42

'C'の場合、カスタムのパディングが必要な場合は、malloc()や事前フォーマットを必要としない[s] printfの代替(より複雑な)使用法があります。

秘訣は、%sに '*'長さ指定子(最小および最大)と、潜在的な最大長までパディング文字で埋められた文字列を使用することです。

「%*。* s」は、左または右のパディングの必要性に応じて、「%s」の前または後に配置できます。

[####Monkey] <-- Left padded, "%*.*s%s"
[Monkey####] <-- Right padded, "%s%*.*s"

PHP printf(ここ)は、%s形式で、一重引用符( ')の後にカスタムパディング文字を使用して、カスタムパディング文字を指定する機能をサポートしていることがわかりました。
printf("[%'#10s]\n", $s); // use the custom padding character '#'
生成:
[####monkey]


他の投稿された回答をここに複製したようです:printfの可変サイズのパディング
J Jorgenson

2

入力文字列にすべてのパディング文字を保持するのに十分なスペースがあることを確認する必要があります。これを試して:

hello最後にヌルターミネータを説明するために、文字列に11バイトを割り当てたことに注意してください。


1

「Hello」を渡した引数は、定数データ領域にあります。char * stringに十分なメモリを割り当てていない限り、他の変数にオーバーランしています。

編集:スタックから定数データ領域に修正されました。


あなたはまだ文字列リテラルを渡しています...:P
Jeremy Ruten

コピーしすぎています。Helloのタイプはchar [6]ですが、1024バイトをコピーしようとしています。それは失敗するだけです。2番目のsizeof(buffer)の代わりにsizeof "Hello"を読み取るように変更します
Johannes Schaub --litb 2008年

1
strncpy(buffer、 "Hello"、sizeof(buffer)); すでにバッファ全体が「\ 0」で満たされているため、memset()は冗長です。
クリスヤング

@ litb、strncpy:num文字がコピーされる前にソースC文字列(ヌル文字で通知される)の終わりが見つかった場合、合計num文字が書き込まれるまで、宛先にゼロが埋め込まれます。
Eugene Yokota

@Chris、バッファ後のmemsetは習慣的なものです。そのままにしておきます。
Eugene Yokota

1

わかりました、理にかなっています。だから私はこれをしました:

ありがとう!


1

str1を解放することを忘れないでください
Pierre-Louis Sauvage 2017年

1

出力:


0

関数自体は私にはうまく見えます。問題は、文字列にその数の文字を埋め込むのに十分なスペースを割り当てていないことである可能性があります。将来size_of_string、関数に引数を渡すことでこの問題を回避し、長さがサイズより大きくなりそうなときに文字列を埋めないようにすることができます。


0

このスレッドで元の質問を形成する関数で間違いなく間違っていることの1つは、パラメーターとして渡された文字列リテラルの末尾に余分な文字を連結していることです。これにより、予測できない結果が生じます。関数の呼び出し例では、文字列リテラル「Hello」がプログラムにハードコードされているため、おそらくその末尾に連結すると、危険なほどコードが上書きされます。元の文字列よりも大きい文字列を返したい場合は、動的に割り当てることを確認し、完了したら呼び出し元のコードで削除する必要があります。


0
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.