1つの文字列を取得し、スペースなどの区切り文字で2つに分割し、2つの部分を2つの別々の文字列に割り当てる方法を考えていました。 strtok()
を使用しようとしましたが、役に立ちませんでした。
#include <string.h>
char *token;
char line[] = "SEVERAL WORDS";
char *search = " ";
// Token will point to "SEVERAL".
token = strtok(line, search);
// Token will point to "WORDS".
token = strtok(NULL, search);
一部のオペレーティングシステムでは、strtok
のmanページで言及されていることに注意してください。
このインターフェイスはstrsep(3)によって廃止されました。
strsep
の例を以下に示します。
char* token;
char* string;
char* tofree;
string = strdup("abc,def,ghi");
if (string != NULL) {
tofree = string;
while ((token = strsep(&string, ",")) != NULL)
{
printf("%s\n", token);
}
free(tofree);
}
このような目的のために、私はstrtok()の代わりにstrtok_r()を使用する傾向があります。
例えば ...
int main (void) {
char str[128];
char *ptr;
strcpy (str, "123456 789asdf");
strtok_r (str, " ", &ptr);
printf ("'%s' '%s'\n", str, ptr);
return 0;
}
これは出力されます...
「123456」「789asdf」
さらに区切り文字が必要な場合は、ループします。
お役に立てれば。
char *line = strdup("user name"); // don't do char *line = "user name"; see Note
char *first_part = strtok(line, " "); //first_part points to "user"
char *sec_part = strtok(NULL, " "); //sec_part points to "name"
注:strtok
は文字列を変更するため、文字列リテラルへのポインターを渡さないでください。
その例にはstrtok()を使用できます:それは私のために機能します
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
これは、strtok()
のような関数を実装する方法です( zStringと呼ばれるBSDライセンスのC用文字列処理ライブラリ から取得)。
以下の関数は、標準のstrtok()
とは異なりますが、標準のstrtok()
はそうではありません。
char *zstring_strtok(char *str, const char *delim) {
static char *static_str=0; /* var to store last address */
int index=0, strlength=0; /* integers for indexes */
int found = 0; /* check if delim is found */
/* delimiter cannot be NULL
* if no more char left, return NULL as well
*/
if (delim==0 || (str == 0 && static_str == 0))
return 0;
if (str == 0)
str = static_str;
/* get length of string */
while(str[strlength])
strlength++;
/* find the first occurance of delim */
for (index=0;index<strlength;index++)
if (str[index]==delim[0]) {
found=1;
break;
}
/* if delim is not contained in str, return str */
if (!found) {
static_str = 0;
return str;
}
/* check for consecutive delimiters
*if first char is delim, return delim
*/
if (str[0]==delim[0]) {
static_str = (str + 1);
return (char *)delim;
}
/* terminate the string
* this assignmetn requires char[], so str has to
* be char[] rather than *char
*/
str[index] = '\0';
/* save the rest of the string */
if ((str + index + 1)!=0)
static_str = (str + index + 1);
else
static_str = 0;
return str;
}
以下は、使用法を示すサンプルコードです。
Example Usage
char str[] = "A,B,,,C";
printf("1 %s\n",zstring_strtok(s,","));
printf("2 %s\n",zstring_strtok(NULL,","));
printf("3 %s\n",zstring_strtok(NULL,","));
printf("4 %s\n",zstring_strtok(NULL,","));
printf("5 %s\n",zstring_strtok(NULL,","));
printf("6 %s\n",zstring_strtok(NULL,","));
Example Output
1 A
2 B
3 ,
4 ,
5 C
6 (null)
Whileループを使用することもできます(標準ライブラリのstrtok()
はここでも同じ結果になります)。
char s[]="some text here;
do {
printf("%s\n",zstring_strtok(s," "));
} while(zstring_strtok(NULL," "));
元の文字列を変更する場合は、区切り文字を\0
に置き換えるだけで済みます。元のポインターは最初の文字列を指し、区切り文字の後の文字を指すポインターは2番目の文字列を指します。良いことは、新しい文字列バッファーを割り当てることなく、両方のポインターを同時に使用できることです。
Char配列が割り当てられている場合は、'\0'
を必要な場所に配置できます。次に、新しく挿入された'\0'
の直後の位置を指す新しいchar *ポインターをポイントします。
'\0'
を配置した場所にもよりますが、これは元の文字列を破棄します
できるよ:
char str[] ="Stackoverflow Serverfault";
char piece1[20] = ""
,piece2[20] = "";
char * p;
p = strtok (str," "); // call the strtok with str as 1st arg for the 1st time.
if (p != NULL) // check if we got a token.
{
strcpy(piece1,p); // save the token.
p = strtok (NULL, " "); // subsequent call should have NULL as 1st arg.
if (p != NULL) // check if we got a token.
strcpy(piece2,p); // save the token.
}
printf("%s :: %s\n",piece1,piece2); // prints Stackoverflow :: Serverfault
複数のトークンを期待する場合は、strtok
の戻り値がstrtok
になるまで、whileループでNULL
の2回目以降の呼び出しを呼び出す方が適切です。