用多个空格在 C 中打破一个字符串
Breaking a string in C with multiple spaces
好的,所以我的代码目前将单个字符串拆分为:"hello world" 为:
hello
world
但是当我在字符串之间、之前或之后有多个 space 时,我的代码将无法运行。它需要 space 并将其计为要分析的 word/number。例如,如果我在 hello 和 world 之间放入两个 spaces,我的代码将产生:
hello
(a space character)
world
space其实算作一个word/token。
int counter = 0;
int index = strcur->current_index;
char *string = strcur->myString;
char token_buffer = string[index];
while(strcur->current_index <= strcur->end_index)
{
counter = 0;
token_buffer = string[counter+index];
while(!is_delimiter(token_buffer) && (index+counter)<=strcur->end_index)//delimiters are: '[=12=]','\n','\r',' '
{
counter++;
token_buffer = string[index+counter];
}
char *output_token = malloc(counter+1);
strncpy(output_token,string+index,counter);
printf("%s \n", output_token);
TKProcessing(output_token);
//update information
counter++;
strcur->current_index += counter;
index += counter;
}
我可以在我的循环中看到问题区域,但我对如何解决这个问题感到有点困惑。必须感谢任何帮助。
使用标准 C 库函数 strtok()。
而不是重新开发这样的标准功能。
这是相关的 related manual page。
您的情况可以如下使用:
#include <string.h>
char *token;
token = strtok (string, " \r\n");
// do something with your first token
while (token != NULL)
{
// do something with subsequents tokens
token = strtok (NULL, " \r\n");
}
如您所见,每次使用相同参数对 strtok 的后续调用都会向您发回指向下一个标记的 char* 地址。
如果您正在处理线程程序,您可以使用 strtok_r() C 函数。
第一次调用它应该与 strtok() 相同,但后续调用将 NULL 作为第一个参数传递。 :
#include <string.h>
char *token;
char *saveptr;
token = strtok_r(string, " \r\n", &saveptr)
// do something with your first token
while (token != NULL)
{
// do something with subsequents tokens
token = strtok_r(NULL, " \r\n", &saveptr)
}
从编码的角度来看,如果您想知道如何在没有库的情况下执行此操作作为练习,那么在您 运行 进入第一个定界符后,您的循环就会中断。然后当你循环到第二个定界符时,你不进入第二个while循环并再次打印新行。你可以把
//update information
while(is_delimiter(token_buffer) && (index+counter)<=strcur->end_index)
{
counter++;
token_buffer = string[index+counter];
}
只需将流程令牌逻辑放入if(counter > 0){...}
,这使得malloc
仅在有真实令牌时发生。像这样
if(counter > 0){ // it means has a real word, not delimeters
char *output_token = malloc(counter+1);
strncpy(output_token,string+index,counter);
printf("%s \n", output_token);
TKProcessing(output_token);
}
好的,所以我的代码目前将单个字符串拆分为:"hello world" 为:
hello
world
但是当我在字符串之间、之前或之后有多个 space 时,我的代码将无法运行。它需要 space 并将其计为要分析的 word/number。例如,如果我在 hello 和 world 之间放入两个 spaces,我的代码将产生:
hello
(a space character)
world
space其实算作一个word/token。
int counter = 0;
int index = strcur->current_index;
char *string = strcur->myString;
char token_buffer = string[index];
while(strcur->current_index <= strcur->end_index)
{
counter = 0;
token_buffer = string[counter+index];
while(!is_delimiter(token_buffer) && (index+counter)<=strcur->end_index)//delimiters are: '[=12=]','\n','\r',' '
{
counter++;
token_buffer = string[index+counter];
}
char *output_token = malloc(counter+1);
strncpy(output_token,string+index,counter);
printf("%s \n", output_token);
TKProcessing(output_token);
//update information
counter++;
strcur->current_index += counter;
index += counter;
}
我可以在我的循环中看到问题区域,但我对如何解决这个问题感到有点困惑。必须感谢任何帮助。
使用标准 C 库函数 strtok()。
而不是重新开发这样的标准功能。
这是相关的 related manual page。
您的情况可以如下使用:
#include <string.h>
char *token;
token = strtok (string, " \r\n");
// do something with your first token
while (token != NULL)
{
// do something with subsequents tokens
token = strtok (NULL, " \r\n");
}
如您所见,每次使用相同参数对 strtok 的后续调用都会向您发回指向下一个标记的 char* 地址。
如果您正在处理线程程序,您可以使用 strtok_r() C 函数。
第一次调用它应该与 strtok() 相同,但后续调用将 NULL 作为第一个参数传递。 :
#include <string.h>
char *token;
char *saveptr;
token = strtok_r(string, " \r\n", &saveptr)
// do something with your first token
while (token != NULL)
{
// do something with subsequents tokens
token = strtok_r(NULL, " \r\n", &saveptr)
}
从编码的角度来看,如果您想知道如何在没有库的情况下执行此操作作为练习,那么在您 运行 进入第一个定界符后,您的循环就会中断。然后当你循环到第二个定界符时,你不进入第二个while循环并再次打印新行。你可以把
//update information
while(is_delimiter(token_buffer) && (index+counter)<=strcur->end_index)
{
counter++;
token_buffer = string[index+counter];
}
只需将流程令牌逻辑放入if(counter > 0){...}
,这使得malloc
仅在有真实令牌时发生。像这样
if(counter > 0){ // it means has a real word, not delimeters
char *output_token = malloc(counter+1);
strncpy(output_token,string+index,counter);
printf("%s \n", output_token);
TKProcessing(output_token);
}