スペースを区切り文字として使用して文字列をトークン化しようとしましたが、機能しません。なぜ機能しないのかについての提案はありますか?
編集:以下を使用したトークン化:
strtok(string, " ");
コードは次のようなものです
pch = strtok (str," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ");
}
次のようにします:
char s[256];
strcpy(s, "one two three");
char* token = strtok(s, " ");
while (token) {
printf("token: %s\n", token);
token = strtok(NULL, " ");
}
注:strtok
は文字列をトークン化するため、const char*
にはできません。
strtok
の使用例を次に示します。strtok
は入力文字列を破壊することに注意してください(したがって、文字列定数にeverを使用することはできません)
char *p = strtok(str, " ");
while(p != NULL) {
printf("%s\n", p);
p = strtok(NULL, " ");
}
基本的に注意すべきことは、NULL
の最初のパラメーターとしてstrtok
を渡すと、以前にトークン化した文字列から次のトークンを取得するように指示することです。
追加の変数を導入することにより、コードを簡素化できます。
#include <string.h>
#include <stdio.h>
int main()
{
char str[100], *s = str, *t = NULL;
strcpy(str, "a space delimited string");
while ((t = strtok(s, " ")) != NULL) {
s = NULL;
printf(":%s:\n", t);
}
return 0;
}
このコードはPIC18Fプロセッサで実行することを目的としているため、できる限り少ないポインターを使用して、値を分割するためにいくつかの文字列関数を作成しました。これらのプロセッサは、使用可能な空きRAMがほとんどない場合、ポインタを実際に使用できません。
#include <stdio.h>
#include <string.h>
char POSTREQ[255] = "pwd=123456&apply=Apply&d1=88&d2=100&pwr=1&mpx=Internal&stmo=Stereo&proc=Processor&cmp=Compressor&ip1=192&ip2=168&ip3=10&ip4=131&gw1=192&gw2=168&gw3=10&gw4=192&pt=80&lic=&A=A";
int findchar(char *string, int Start, char C) {
while((string[Start] != 0)) { Start++; if(string[Start] == C) return Start; }
return -1;
}
int findcharn(char *string, int Times, char C) {
int i = 0, pos = 0, fnd = 0;
while(i < Times) {
fnd = findchar(string, pos, C);
if(fnd < 0) return -1;
if(fnd > 0) pos = fnd;
i++;
}
return fnd;
}
void mid(char *in, char *out, int start, int end) {
int i = 0;
int size = end - start;
for(i = 0; i < size; i++){
out[i] = in[start + i + 1];
}
out[size] = 0;
}
void getvalue(char *out, int index) {
mid(POSTREQ, out, findcharn(POSTREQ, index, '='), (findcharn(POSTREQ, index, '&') - 1));
}
void main() {
char n_pwd[7];
char n_d1[7];
getvalue(n_d1, 1);
printf("Value: %s\n", n_d1);
}
連続する区切り文字を認識する機能を備えた別のstrtok()
実装があります(標準ライブラリのstrtok()
にはこれがありません)
この関数は、BSDライセンスの文字列ライブラリの一部であり、 zString と呼ばれます。あなたは貢献することを歓迎します:)
https://github.com/fnoyanisi/zString
_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;
}
_
前の投稿で述べたように、strtok()
、または上記で実装したものは_static *char
_変数に依存しており、連続する呼び出し間の最後の区切り文字の位置を保持するため、処理中は特に注意が必要ですマルチスレッドアプリケーション。
Strtokのドキュメントを読むと、最初の「初期化」呼び出しの後にNULLポインターを渡す必要があることがわかります。たぶんあなたはそれをしなかった。もちろん推測です。