C 中的字符串标记

发布于 2024-07-08 14:15:49 字数 260 浏览 12 评论 0原文

我一直在尝试使用空格作为分隔符来标记字符串,但它不起作用。 有人对为什么它不起作用有建议吗?

编辑:标记化使用:

strtok(string, " ");

代码如下

pch = strtok (str," ");
while (pch != NULL)
{
  printf ("%s\n",pch);
  pch = strtok (NULL, " ");
}

I have been trying to tokenize a string using SPACE as delimiter but it doesn't work. Does any one have suggestion on why it doesn't work?

Edit: tokenizing using:

strtok(string, " ");

The code is like the following

pch = strtok (str," ");
while (pch != NULL)
{
  printf ("%s\n",pch);
  pch = strtok (NULL, " ");
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

瑕疵 2024-07-15 14:15:49

这样做:

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*

Do it like this:

char s[256];
strcpy(s, "one two three");
char* token = strtok(s, " ");
while (token) {
    printf("token: %s\n", token);
    token = strtok(NULL, " ");
}

Note: strtok modifies the string its tokenising, so it cannot be a const char*.

鲜肉鲜肉永远不皱 2024-07-15 14:15:49

以下是 strtok 用法的示例,请记住 strtok 会破坏其输入字符串(因此永远不能用于字符串常量

char *p = strtok(str, " ");
while(p != NULL) {
    printf("%s\n", p);
    p = strtok(NULL, " ");
}

基本上需要注意的是,将 NULL 作为第一个参数传递给 strtok 会告诉它从之前标记的字符串中获取下一个标记。

Here's an example of strtok usage, keep in mind that strtok is destructive of its input string (and therefore can't ever be used on a string constant

char *p = strtok(str, " ");
while(p != NULL) {
    printf("%s\n", p);
    p = strtok(NULL, " ");
}

Basically the thing to note is that passing a NULL as the first parameter to strtok tells it to get the next token from the string it was previously tokenizing.

缺⑴份安定 2024-07-15 14:15:49

strtok 可能非常危险。 它不是线程安全的。 它的预期用途是在循环中一遍又一遍地调用,并传入上一次调用的输出。 strtok 函数有一个内部变量,用于存储 strtok 调用的状态。 这种状态并不是每个线程独有的——它是全局的。 如果任何其他代码在另一个线程中使用 strtok,则会出现问题。 也不是您想要追踪的那种问题!

我建议寻找正则表达式实现,或使用 sscanf 来分解字符串。

试试这个:

char strprint[256];
char text[256];
strcpy(text, "My string to test");
while ( sscanf( text, "%s %s", strprint, text) > 0 ) {
   printf("token: %s\n", strprint);
}

注意:“文本”字符串在分离时被破坏。 这可能不是首选行为 =)

strtok can be very dangerous. It is not thread safe. Its intended use is to be called over and over in a loop, passing in the output from the previous call. The strtok function has an internal variable that stores the state of the strtok call. This state is not unique to each thread - it is global. If any other code uses strtok in another thread, you get problems. Not the kind of problems you want to track down either!

I'd recommend looking for a regex implementation, or using sscanf to pull apart the string.

Try this:

char strprint[256];
char text[256];
strcpy(text, "My string to test");
while ( sscanf( text, "%s %s", strprint, text) > 0 ) {
   printf("token: %s\n", strprint);
}

Note: The 'text' string is destroyed as it's separated. This may not be the preferred behaviour =)

∝单色的世界 2024-07-15 14:15:49

您可以通过引入额外的变量来简化代码。

#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;
}

You can simplify the code by introducing an extra variable.

#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;
}
绝不放开 2024-07-15 14:15:49

我制作了一些字符串函数来分割值,尽可能使用更少的指针,因为此代码旨在在 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);
} 

I've made some string functions in order to split values, by using less pointers as I could because this code is intended to run on PIC18F processors. Those processors does not handle really good with pointers when you have few free RAM available:

#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);
} 
眼泪也成诗 2024-07-15 14:15:49

在阅读 strtok 文档时,我发现您需要在第一次“初始化”调用后传入 NULL 指针。 也许你没有这样做。 当然只是猜测。

When reading the strtok documentation, I see you need to pass in a NULL pointer after the first "initializing" call. Maybe you didn't do that. Just a guess of course.

贵在坚持 2024-07-15 14:15:49

这是另一个 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 变量来保留连续调用之间最后一个分隔符的位置,因此应该格外小心在处理多线程应用程序时采取。

Here is another strtok() implementation, which has the ability to recognize consecutive delimiters (standard library's strtok() does not have this)

The function is a part of BSD licensed string library, called zString. You are more than welcome to contribute :)

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;
}

As mentioned in previous posts, since strtok(), or the one I implmented above, relies on a static *char variable to preserve the location of last delimiter between consecutive calls, extra care should be taken while dealing with multi-threaded aplications.

弱骨蛰伏 2024-07-15 14:15:49
int not_in_delimiter(char c, char *delim){

    while(*delim != '\0'){
            if(c == *delim) return 0;
            delim++;
    }
    return 1;
}

char *token_separater(char *source, char *delimiter, char **last){

char *begin, *next_token;
char *sbegin;

/*Get the start of the token */
if(source)
  begin = source;
else
  begin = *last;

sbegin = begin;

/*Scan through the string till we find character in delimiter. */
while(*begin != '\0' && not_in_delimiter(*begin, delimiter)){
       begin++;
}

/* Check if we have reached at of the string */
if(*begin == '\0') {
/* We dont need to come further, hence return NULL*/
   *last = NULL;
    return sbegin;
}
/* Scan the string till we find a character which is not in delimiter */
 next_token  = begin;
 while(next_token != '\0' && !not_in_delimiter(*next_token, delimiter))    {
    next_token++;
 }
 /* If we have not reached at the end of the string */
 if(*next_token != '\0'){
  *last = next_token--;
  *next_token = '\0';
   return sbegin;
}
}

 void main(){

    char string[10] = "abcb_dccc";
    char delim[10] = "_";
    char *token = NULL;
    char *last = "" ;
    token  = token_separater(string, delim, &last);
    printf("%s\n", token);
    while(last){
            token  = token_separater(NULL, delim, &last);
            printf("%s\n", token);
    }

可以在我的个人资料中提到的博客中阅读详细分析:)

int not_in_delimiter(char c, char *delim){

    while(*delim != '\0'){
            if(c == *delim) return 0;
            delim++;
    }
    return 1;
}

char *token_separater(char *source, char *delimiter, char **last){

char *begin, *next_token;
char *sbegin;

/*Get the start of the token */
if(source)
  begin = source;
else
  begin = *last;

sbegin = begin;

/*Scan through the string till we find character in delimiter. */
while(*begin != '\0' && not_in_delimiter(*begin, delimiter)){
       begin++;
}

/* Check if we have reached at of the string */
if(*begin == '\0') {
/* We dont need to come further, hence return NULL*/
   *last = NULL;
    return sbegin;
}
/* Scan the string till we find a character which is not in delimiter */
 next_token  = begin;
 while(next_token != '\0' && !not_in_delimiter(*next_token, delimiter))    {
    next_token++;
 }
 /* If we have not reached at the end of the string */
 if(*next_token != '\0'){
  *last = next_token--;
  *next_token = '\0';
   return sbegin;
}
}

 void main(){

    char string[10] = "abcb_dccc";
    char delim[10] = "_";
    char *token = NULL;
    char *last = "" ;
    token  = token_separater(string, delim, &last);
    printf("%s\n", token);
    while(last){
            token  = token_separater(NULL, delim, &last);
            printf("%s\n", token);
    }

}

You can read detail analysis at blog mentioned in my profile :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文