89

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

char *StringPadRight(char *string, int padded_len, char *pad) {
    int len = (int) strlen(string);
    if (len >= padded_len) {
        return string;
    }
    int i;
    for (i = 0; i < padded_len - len; i++) {
        strcat(string, pad);
    }
    return string;
}

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

4

10 に答える 10

190

%-10s をフォーマット文字列として使用すると、10 文字の長さのフィールドに入力が埋め込まれます。

printf("|%-10s|", "Hello");

出力します

|Hello     |

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

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

于 2008-11-10T01:50:15.320 に答える
46

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

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

int targetStrLen = 10;           // Target output length  
const char *myString="Monkey";   // String for output 
const char *padding="#####################################################";

int padLen = targetStrLen - strlen(myString); // Calc Padding length
if(padLen < 0) padLen = 0;    // Avoid negative length

printf("[%*.*s%s]", padLen, padLen, padding, myString);  // LEFT Padding 
printf("[%s%*.*s]", myString, padLen, padLen, padding);  // RIGHT Padding 

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

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

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

于 2012-03-16T16:34:38.640 に答える
2

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

char hello[11] = "Hello";
StringPadRight(hello, 10, "0");

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

于 2008-11-10T01:25:13.670 に答える
1

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

char buffer[1024];
memset(buffer, 0, sizeof(buffer));
strncpy(buffer, "Hello", sizeof(buffer));
StringPadRight(buffer, 10, "0");

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

于 2008-11-10T01:25:04.497 に答える
1

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

    char foo[10] = "hello";
    char padded[16];
    strcpy(padded, foo);
    printf("%s", StringPadRight(padded, 15, " "));

ありがとう!

于 2008-11-10T01:37:17.250 に答える
1
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

using namespace std;

int main() {
    // your code goes here
    int pi_length=11; //Total length 
    char *str1;
    const char *padding="0000000000000000000000000000000000000000";
    const char *myString="Monkey";

    int padLen = pi_length - strlen(myString); //length of padding to apply

    if(padLen < 0) padLen = 0;   

    str1= (char *)malloc(100*sizeof(char));

    sprintf(str1,"%*.*s%s", padLen, padLen, padding, myString);

    printf("%s --> %d \n",str1,strlen(str1));

    return 0;
}
于 2016-08-01T11:32:48.463 に答える
0

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

于 2008-11-10T01:25:27.710 に答える
0

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

于 2015-01-21T15:02:32.843 に答える