2

int snprintf(char *str, size_t size, const char *format, ...); 特定の文字数をに書き込むことができますstr

c文字列から特定の文字数を読み取るにはどうすればよいですか?

よろしく

4

5 に答える 5

6

format引数で数値を渡すことができます。

char buf[21];
sscanf(str, "%20s", buf);

これにより、最大20文字がに読み込まれますbuf

コンパイル時に読み取るデータの量がわからない場合は、実行時にフォーマット文字列を準備できます。

char format[20];
sprintf(format, "%%%ds", howMuchToRead);
sscanf(str, format, buf);
于 2012-07-18T10:53:18.567 に答える
4

sscanfとソリューションの両方の代わりに、高精度strncpyの指定子を使用することもできます(20文字だけを印刷するなど)。このSO投稿では、 C文字列の高精度指定子について説明しています。手順は基本的にソリューションと同じです。フォーマット文字列を作成し、それを使用して必要な文字をキャプチャします。上記のフォーマット指定子などを使用している 場合、文字列に空白が含まれていると20文字になるとは限りません。空白が検出された場合は、空白までしか文字を取得できません(空白は関数ファミリーの区切り文字であるため)。代わりに、次のようなものを利用する必要があります"%.20s"sscanf
sscanf"%20s"scanf%20[^\n][^\n]改行までの読み取りを示し、20はスキャンする文字数を指定します。これらはすべて、次のサンプルで確認できます。

#include <stdio.h>
#include <string.h>

int main(void) {
        char format[20] = {0};
        char buf[50] = {0};
        char str[] = "Hello World! How are you?";
        size_t howMuchToRead = 8;

        /* Using sscanf - till whitespace or size specified */
        snprintf(format, sizeof format, "%%%zus", howMuchToRead);
        sscanf(str, format, buf);
        printf("Using sscanf with %%8s format :%s\n", buf);

        /* Using sscanf - read everything upto newline */
        snprintf(format, sizeof format, "%%%zu[^\n]", howMuchToRead);
        sscanf(str, format, buf);
        printf("Using sscanf with %%8[^\\n] format :%s\n", buf);

        /* Using precision specifier */
        snprintf(format, sizeof format, "%%.%zus", howMuchToRead);
        snprintf(buf, sizeof buf, format, str);
        printf("Using precision specifier :%s\n", buf);
        return 0;
}
/*
Output:
Using sscanf with %8s format :Hello
Using sscanf with %8[^\n] format :Hello Wo
Using precision specifier :Hello Wo
*/

そして、sinelawの答えは、あなたが注意しなければならない非常に重要な点を示しています。
お役に立てれば!

于 2012-07-18T18:02:01.263 に答える
2

strncpyまたはを使用できますmemcpy。ただし、場合によっては終了文字strncpyが追加されない場合があり、追加されない場合があることに注意してください。また、文字列の終わりをまったくチェックせず、要求したバイト数をコピーするだけです。'\0'memcpymemcpy

于 2012-07-18T10:53:39.530 に答える
2

あなたが使用することができますsscanf

int sscanf(const char *str, const char *format, ...);

例えば:

char out[4];
sscanf("foo", "%3s", &out);

もちろん、もっと面白いこともできます。

int value;
sscanf("value=10", "value=%d", &value);
于 2012-07-18T10:55:30.857 に答える
2

sscanfscanf関数のように、問題があります。GNUのマンページにあるように:

指定されたフォーマット指定子には十分なアドレス引数が必要です。そうでない場合、結果は予測不可能であり、恐らく悲惨です。

したがって、回避する必要のある問題が1つあります(一部のコンパイラには、これらの関数について具体的に警告するハックがありますが、コンパイラは、正しい量またはタイプの引数を渡していることを確認できません)。この問題の一部は、フォーマット文字列に最大バッファサイズをハードコーディングする必要があることでもあります(これにより、バッファオーバーフローを防ぐために整数定数を使用することが難しくなります)。

あなたのユースケースは単に文字列から特定の数の文字をコピーすることなので、Joachim Pileborgの答えが示唆するように、私はただ使用しますstrncpy(そして必ず終了を設定します)。'\0'長さパラメーターには、入力バッファーと出力バッファーの両方の最小長から、終了を収容するために1を引いたものを使用する必要がありますnul

言い換えれば(テストされていない):

strncpy(dest, src, 
        MIN(NUM_OF_CHARS_TO_COPY, 
            MIN(DEST_BUFFER_SIZE, SRC_BUFFER_SIZE)) - 1);

ここで、は整数MIN(a,b)と同等です。a < b ? a : b

于 2012-07-18T14:07:00.517 に答える