我有一个字符串,例如"第一个"我想要的结果是这个输出:
first
second
但我得到的输出是:
first
first second
我知道在我的更新语句或创建子字符串时都存在问题。如果有人能帮助我,那就太棒了。以下是我的代码:
int counter = 0; //counter used in loop
int index = test->current_index; //holds the current index of my string, it's initially 0
char *string = test->myString; //holds the whole string
char token_buffer = string[index];
//before loop: index = 0, counter = 0
while(test->current_index <= test->end_index) //test->end_index holds last index of string
{
while(token_buffer != ' ')
{
counter++;
token_buffer = string[index + counter];
}
char *output_token = malloc(counter+1);
strncpy( output_token, string, counter );
//printing token
printf("%s \n", output_token);
//update loop (possible problem area!)
test->current_index += counter;
index += counter;
token_buffer+=string[counter];
counter =0;
}
return 0;
}
答案 0 :(得分:3)
有许多方法可以将字符串拆分为在空格中分隔它们的标记。诀窍是使其尽可能高效且相当稳健,而不会使其过于复杂。两种基本方法是使用(1)“inch-worm”方法(简单地使用2个指针,一个开始和结束指针,一次处理字符串一个字符,或者(2)使用其中一个标记化libc提供的功能(例如strtok
或strsep
)。
使用英制蠕虫方法,您可以完全控制并具有竞争灵活性,但是当您按下字符串时,可以 跟踪每个指针指向的位置。 (熟悉这种方法的一个好方法是在 paper 上编写你正在解析的字符串,并根据需要手动推进指针 - 编写你的例程)。一个例子:
char *string = test->myString; //holds the whole string
char *p = string;
while (*p) /* while not end of string */
{
char *sp = p; /* set a start pointer */
while (*p && *p != ' ') p++; /* advance to space */
char *output_token = malloc (p - sp + 1); /* allocate */
strncpy (output_token, sp, p - sp); /* copy */
output_token[p - sp] = 0; /* force null-termination */
printf(" %s\n", output_token);
free (output_token); /* free if not needed */
while (*p && *p == ' ') p++; /* find next non-space */
}
第二种方法使用strtok
做同样的事情。 注意:您可以随意在分隔符字符串中放置任意数量的字符,并且不要求每次调用strtok
时它们都是相同的字符。这可以提供很大的灵活性。一个例子:
char *string = test->myString; //holds the whole string
char *p = string; /* pointer to string */
char *tok = NULL; /* pointer to token */
for (tok = strtok (p, " "); tok; tok = strtok (NULL, " \n"))
{
char *output_token = strdup (tok); /* allocate & copy at once */
printf(" %s\n", output_token);
free (output_token);
}
如果您想将两者与示例进行比较,可以使用以下简短示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char **argv) {
// char *string = test->myString; //holds the whole string
char *string = argc > 1 ? argv[1]: "some string with spaces";
printf ("\n With pointer arithmetic:\n\n");
char *p = string;
while (*p) /* while not end of string */
{
char *sp = p; /* set a start pointer */
while (*p && *p != ' ') p++; /* advance to space */
char *output_token = malloc (p - sp + 1); /* allocate */
strncpy (output_token, sp, p - sp); /* copy */
output_token[p - sp] = 0; /* force null-termination */
printf(" %s\n", output_token);
free (output_token); /* free if not needed */
while (*p && *p == ' ') p++; /* find next non-space */
}
printf ("\n With strtok:\n\n");
p = string;
char *tok = NULL; /* pointer to each token in string */
/* using strtok to separate string into tokens at spaces */
for (tok = strtok (p, " "); tok; tok = strtok (NULL, " \n"))
{
char *output_token = strdup (tok);
printf(" %s\n", output_token);
free (output_token);
}
return 0;
}
示例/输出强>
$ ./bin/charbufsplit "This is a longer string with many more spaces"
With pointer arithmetic:
This
is
a
longer
string
with
many
more
spaces
With strtok:
This
is
a
longer
string
with
many
more
spaces
答案 1 :(得分:0)
问题似乎是调用strncpy
。
用:
strncpy( output_token, string, counter );
您正在复制counter
string
开头的output_token
个字符。要致电strncpy
,您最常将源字符串移至current_index
。类似的东西:
strncpy( output_token, (char*)(string+test->current_index), counter );
在循环结束时。
答案 2 :(得分:0)
您的代码中有两个错误:
strncpy
中,每次复制到output_token
时,您都会从string
的起始地址开始复制。while
循环条件token_buffer != ' '
中。由于在字符串末尾,您没有空格,因此您的计数器将继续增加并超出test->end_index
,直到它读取空格。校正:
counter = 0;
token_buffer = string[counter+index];
while(token_buffer != ' ' && (index+counter)<=test->end_index) //since counter is always set to zero before this loop executes.
{
counter++;
token_buffer = string[index+counter];
}
char *output_token = calloc(counter+1);
strncpy(output_token,string+index,counter);
printf("%s \n", output_token);
counter++; //This is required since when the loop exit, counter would be at the position of ' '.
test->current_index += counter;
index += counter;
在主循环中添加此内容。