web-dev-qa-db-ja.com

Cでchar []の一部を印刷する最も簡単な方法

char* str = "0123456789"最初と最後の3文字を切り取り、真ん中だけを印刷したいのですが、最も簡単で安全な方法は何ですか。

ここでの秘訣は、カットする部分と印刷する部分のサイズが可変であるため、char *が非常に長くなるか、非常に小さくなる可能性があることです。

27
Edu Felipe

printf()と特別なフォーマット文字列を使用できます:

char *str = "0123456789";
printf("%.6s\n", str + 1);

%s変換指定子の精度は、印刷する最大文字数を指定します。変数を使用して、実行時に精度を指定することもできます。

int length = 6;
char *str = "0123456789";    
printf("%.*s\n", length, str + 1);

この例では、*は次の引数(length)に%s変換の精度が含まれることを示すために使用され、対応する引数はintでなければなりません。

上記のように、ポインター演算を使用して開始位置を指定できます。

[編集]

もう1つ、文字列が精度指定子より短い場合、出力される文字数は少なくなります。たとえば、

int length = 10;
char *str = "0123456789";
printf("%.*s\n", length, str + 5);

56789」を出力します。常に特定の数の文字を印刷する場合は、最小フィールド幅と精度の両方を指定します。

printf("%10.10s\n", str + 5);

または

printf("%*.*s\n", length, length, str + 5);

印刷されます:

"     56789"

マイナス記号を使用して、フィールドの出力を左揃えにすることができます。

printf("%-10.10s\n", str + 5);

最後に、最小フィールド幅と精度は異なる場合があります。

printf("%8.5s\n", str);

8文字のフィールドに最大5文字を右揃えで印刷します。

58
Robert Gamble

ロバート・ギャンブルとスティーブは別々にほとんどの曲を持っています。全体に組み立て:

void print_substring(const char *str, int skip, int tail)
{
    int len = strlen(str);
    assert(skip >= 0);
    assert(tail >= 0 && tail < len);
    assert(len > skip + tail);
    printf("%.*s", len - skip - tail, str + skip);
}

例の呼び出し:

print_substring("0123456789", 1, 3);
9

データを変更してもかまわない場合は、ポインタ演算を実行するだけです。これは、strが配列ではなくcharポインタであると想定しています。

char string[] = "0123456789";
char *str = string;

str += 3; // "removes" the first 3 items
str[4] = '\0'; // sets the 5th item to NULL, effectively truncating the string

printf(str); // prints "3456"
1
Kyle Cronin

ここに私が私の個人的なライブラリから掘り出したクリーンでシンプルな部分文字列関数があります。

char *
substr(const char *src, size_t start, size_t len)
{
  char *dest = malloc(len+1);
  if (dest) {
    memcpy(dest, src+start, len);
    dest[len] = '\0';
  }
  return dest;
}

それはおそらく自明ですが、文字列、開始位置(ゼロから開始)、および長さを取り、元の文字列の部分文字列またはmallocが失敗した場合はnullポインターを返します。返されるポインタは、メモリが不要になったときに呼び出し元がfree 'd'することができます。 Cの精神では、関数は指定された開始位置と長さを検証しません。

0
Robert Gamble