1

次の文字列を 3 つの個別の変数、つまり a、b、c に分けようとしています。

"   mov/1/1/1,0 STR{7}, r7" 

それぞれが文字列の異なるセグメントを保持する必要があります。例:

a = "mov/1/1/1,0"
b = "STR{7}"
c = "r7"

各コマンドの間にスペースまたはタブがある場合があります。これが、このコード部分をよりトリッキーにしている理由です。

文字列操作に ,を使用しようとしましstrtokたが、うまくいきませんでした。

char command[50] = "    mov/1/1/1,0 STR{7}, r7";
char a[10], b[10], c[10];
char * ptr = strtok(command, "\t");
strcpy(a, ptr);
ptr = strtok(NULL, "\t");
strcpy(b, ptr);
ptr = strtok(NULL, ", ");
strcpy(c, ptr);

しかし、これは変数として非常に厄介になりa, bc必要以上の値を保持するようになり、プログラムがクラッシュします。

入力は次のものと異なる場合があります。

"   mov/1/1/1,0 STR{7}, r7"
"jsr /0,0            PRTSTR"
"mov/1/1/0,0         STRADD{5}, LASTCHAR {r3} "

a、b、および c の値は、指定された文字列の別の部分に変更されます。

そのようなマナーには strtok よりも sscanf を使用する方が安全だと言われましたが、なぜ、どのように役立つのかわかりません。

ご意見をいただけるとさらに嬉しいです!

4

3 に答える 3

0

sscanf()と同じ方法で使用できることはご存知かもしれませんがscanf()、違いは、sscanf は文字列からスキャンするのに対し、scanf は標準入力からスキャンすることです。この問題では、このリンク
で行われているように、一連の文字を「常にスキップ」する scanf を指定できます。3 つの文字列すべてをスキャンするためのさまざまな制約セットがあるため、 を使用して、 sscanf() 内のすべての前にこれらの制約 を指定できます。
%*[^...]%s

于 2013-08-17T21:27:59.440 に答える
0

の使用については留保がstrtok()ありますが、それを使用したこのコードは、必要なことを行っているようです。コメントで指摘したように、サンプル文字列"jsr /0,0 PRTSTR"は作品にスパナを投げます。2 番目のフィールドには重要なコンマがありますが、他の 2 つの文字列例では、2 番目のフィールドのコンマは重要ではありません。末尾のコンマを削除する必要がある場合は、このコードに示すように、スペース ベースの分割の後に行うことができます。2 番目のループは関数をテストして、zap_trailing_commas()関数が縮退した場合に動作することを確認し、末尾のコンマをザッピングしますが、バッファーの開始または恐ろしい何かをアンダーフローしません。

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

static void zap_trailing_commas(char *str)
{
    size_t len = strlen(str);
    while (len-- > 0 && str[len] == ',')
        str[len] = '\0';
}

static void splitter(char *command)
{
    char a[20], b[20], c[20];
    char *ptr = strtok(command, " \t");
    strcpy(a, ptr);
    zap_trailing_commas(a);
    ptr = strtok(NULL, " \t");
    strcpy(b, ptr);
    zap_trailing_commas(b);
    ptr = strtok(NULL, " \t");
    strcpy(c, ptr);
    zap_trailing_commas(c);
    printf("<<%s>> <<%s>> <<%s>>\n", a, b, c);
}

int main(void)
{
    char data[][50] =
    {
        "   mov/1/1/1,0 STR{7}, r7",
        "jsr /0,0            PRTSTR",
        "mov/1/1/0,0         STRADD{5}, LASTCHAR {r3} ",
    };

    for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); i++)
        splitter(data[i]);

    char commas[][10] = { "X,,,", "X,,", "X,", "X" };
    for (size_t i = 0; i < sizeof(commas)/sizeof(commas[0]); i++)
    {
        printf("<<%s>> ", commas[i]);
        zap_trailing_commas(&commas[i][1]);
        printf("<<%s>>\n", commas[i]);
    }

    return 0;
}

出力例:

<<mov/1/1/1,0>> <<STR{7}>> <<r7>>
<<jsr>> <</0,0>> <<PRTSTR>>
<<mov/1/1/0,0>> <<STRADD{5}>> <<LASTCHAR>>
<<X,,,>> <<X>>
<<X,,>> <<X>>
<<X,>> <<X>>
<<X>> <<X>>

また、X の代わりにコンマを使用してバリアントをテストしたところ、単一のコンマだけが残されました。

于 2013-08-18T04:01:19.813 に答える