5

文字列をトークンに分割し、データを変数に保存したいと考えています。次の文字列があります。

John|Doe|Melbourne|6270|AU

|次のように、プログラムで使用できるように、それを分割し、すべてのトークンを変数として保持する必要があります。

fname = "John"
lname = "Doe"
city = "Melbourne"
zip = "6270"
country = "AU"

これまでにこれを試してみましたが、最初のトークンにアクセスできますが、残りの方法はわかりません(役に立たないwhileループを除いて):

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

int main (void) {
char str[] = "John|Doe|Melbourne|6270|AU";

strtok(str, "|");

printf("%s\n", str);
return 0;
}
4

5 に答える 5

12
    char fname[32], lname[32], city[32], zip[32], country[32];

    strcpy(fname, strtok(str , "|"));
    strcpy(lname, strtok(NULL, "|"));
    strcpy(city , strtok(NULL, "|"));
    strcpy(zip , strtok(NULL, "|"));
    strcpy(country, strtok(NULL, "|"));

    printf("%s\n", fname);
    printf("%s\n", lname);
    printf("%s\n", city);
    printf("%s\n", zip);
    printf("%s\n", country);
于 2013-06-13T10:59:44.223 に答える
6

形式が一定の場合は、次を使用できますsscanf()

char fname[32], lname[32], city[32], zip[16], country[8];

if(sscanf(str, "%31[^|]|%31[^|]|%31[^|]|%15[^|]%7s",
               fname, lname, city, zip, country) == 5)
{
}

これは、%[]文字セット形式指定子を使用して、「垂直バーを除くすべて」を取得します。幅は、バッファー オーバーランを防ぐために含まれています。

于 2013-06-13T10:56:06.403 に答える
3

strtokトークンへのポインターを返します。連続するトークンを取得するには、最初の引数として NULL を渡します。

#define FIELD_LENGTH 20
#define NUM_FIELDS    5
...
char target[NUM_FIELDS][FIELD_LENGTH];
int field = 0;
...
while ( get_next_string( str )) // where get_next_string retrieves your next
{                                // delimited string
  char *token = strtok( str, "|" );
  while ( token )
  {
    strcpy( target[i++], token );
    token = strtok( NULL, "|" );
  }
}

編集

Golgauth のコメントに対処するために、使用について覚えておくべき重要なことがいくつかありますstrtok

  • 区切り文字の各出現箇所を 0 に置き換えることで入力文字列を変更します。つまり、文字列リテラルでは使用できません。元の文字列を保持したい場合は、に渡すコピーを作成する必要がありstrtokます。
  • 単一の静的バッファを使用して、変更中の文字列を格納し、再入不可にします。複数のスレッドがstrtok異なる文字列をトークン化するために を呼び出すと、スレッド同士が相互に干渉してしまいます (これは競合状態として知られています。プログラムの動作は、どのスレッドが最初に何かにアクセスするかによって異なります)。また、strtok の呼び出しをネストすることはできません (つまり、トークンを取得し、それをサブトークンに分割してから、次のトークンを取得します)。

strtok_sオンラインの 2011 標準では、 Annex K (Bounds-checking インターフェイス) の一部として、より安全な (および IINM 再入可能な) 代替手段について言及しています。一部の実装strtok_rでは、再入可能な関数も提供されます。

于 2013-06-13T10:58:36.050 に答える
3

strtokを呼び出し続けてください

char* name = strtok(str, "|");
char* surname = strtok(NULL, "|");
...
于 2013-06-13T10:55:32.107 に答える
2

それと sscanf を使用できます(指定された区切り文字までの文字列をスキャンできます)

int n; 
char fname[128]= "", lname[128]= "", city[128]= "", zipcode[128]= "", country[128]= "";
n= sscanf str("%127[^|]|%127[^|]|%127[^|]|%127[^|]|%127s", fname, lname, city, zipcode, country); 
if (n==5) {  // five fields scanned

}
于 2013-06-13T10:56:38.887 に答える