2

リストに挿入するデータをキーボードから読み込みたい。たとえば、 と入力した場合ins "name_to_insert" 19930412、文字列は引用符なしnameで name_to_insert とし、 19930412 にする必要があります。2 番目の sscanf を適切に指定する方法がわかりません。date

char op[4], name[30], s[50];
int date;
while (scanf("%[^\n]%*c", s)==1)
{
    sscanf(s, "%s", op);
    if (strcmp(op, "ins")==0)
    {
        sscanf(s, "%*s %[^0-9]%d", name, &date);
        printf("Name is %s and date is %d\n", name, date);
    }
}
4

3 に答える 3

1

名前から最初と最後の文字を削除するだけで、引用符の問題を解決しました。

char op[4], nameTemp[30], *name, s[50];
int date;
while (scanf("%[^\n]%*c", s)==1)
{
    sscanf(s, "%s", op);
    if (strcmp(op, "ins")==0)
    {
        sscanf(s, "%*s %[^0-9]%d", nameTemp, &date);
        name=nameTemp+1;
        name[strlen(name)-2]='\0';
        printf("Name is %s and date is %d\n", name, date);
    }
}
于 2013-03-16T08:33:58.757 に答える
1

あなたはほとんど正しいです。引用符が必須であると仮定すると、scan-set 変換指定子を引用符で囲む必要があります。

if (sscanf(s, "%*s \"%29[^\"]\" %d", name, &date) != 2)
    ...oops...

に注意してください%29[^0-9]'\0'これにより、文字列が 29 バイトと30 バイトの配列に収まる終端の null に制限されます。アウターにも同様のチェックを入れるか、代わりにscanf()使用する必要があります。fgets()scanf()

引用符がオプションの場合は、数字以外の名前をスキャンし、スキャン後に引用符を削除するという、少し手間がかかる作業が必要です。

if (sscanf(s, "%*s %29[^0-9] %d", name, &date) != 2)
    ...oops...

ここにいくつかのテストコードがあります:

#include <stdio.h>

static void scanner(const char *fmt, const char *s)
{
    char name[30];
    int  date;

    if (sscanf(s, fmt, name, &date) != 2)
        printf("Scan failed {%s} and {%s}\n", fmt, s);
    else
        printf("{%s} and {%s} => {%s} %d\n", fmt, s, name, date);
}

int main(void)
{
    char source[][30] =
    {
        "ins \"name in quotes\" 12345",
        "ins name without quotes 12345",
    };
    enum { NUM_SOURCE = sizeof(source) / sizeof(source[0]) };
    char format[][20] =
    {
        "%*s \"%29[^\"]\" %d",
        "%*s %29[^0-9] %d",
    };
    enum { NUM_FORMAT = sizeof(format) / sizeof(format[0]) };

    for (int i = 0; i < NUM_FORMAT; i++)
    {
        for (int j = 0; j < NUM_SOURCE; j++)
            scanner(format[i], source[j]);
    }
    return 0;
}

出力例:

{%*s "%29[^"]" %d} and {ins "name in quotes" 12345} => {name in quotes} 12345
Scan failed {%*s "%29[^"]" %d} and {ins name without quotes 12345}
{%*s %29[^0-9] %d} and {ins "name in quotes" 12345} => {"name in quotes" } 12345
{%*s %29[^0-9] %d} and {ins name without quotes 12345} => {name without quotes } 12345

変換の失敗は予期されたものです。フォーマットは引用符を探しますが、何もありません。

少し異なるハーネスとフォーマット文字列も試しました。

"%*s %1[\"]%29[^\"]%1[\"] %d"

(引用符を保持するために 2 つの 2 文字の文字列q1q2, を渡す) が、引用符が欠落している場合、スキャンは失敗しました。引用符はオプションではありません。

名前には末尾のスペースと 2 番目の形式の引用符があることに注意してください。それらは個別に削除する必要があります。

于 2013-03-16T07:57:18.730 に答える
0
sscanf(s, "%*s \"%[^\"]\" %d", name, &date);
于 2013-03-16T13:26:42.243 に答える