(C) 带有多个 spaces/tabs 的 strtok,用指针检查 null
(C) strtok with multiple spaces/tabs, checking for null with pointer
我正在尝试使用 strtok()
将字符串拆分为两个标记,字符串中可能混有空格和制表符。
所以我做了这个:
struct strstr
{
char *str,
*one,
*two;
};
typedef struct strstr *STRSTR;
void split(STRSTR);
int main()
{
STRSTR str = malloc(sizeof(struct strstr));
str->str = malloc(256);
fgets(str->str, 256, stdin);
split(str);
printf("%s, %s\n", str->one, str->two);
free(str->str);
free(str);
return 0;
}
void split(STRSTR str)
{
int i;
char *temp = str->str;
while(isspace(*(str->str)))
str->str++;
str->one = strtok(str->str, " \t");
for(i = 0; i < strlen(str->one); i++)
{
if(!isspace(str->one[i]))
str->str++;
}
str->str++;
if(str->str != NULL)
{
puts("In null if");
str->two = strtok(str->str, "");
}
str->str = temp;
}
所以比如你输入Hello Earth lingss
,它会打印出Hello, Earth lingss
,这是完美的。
但是,如果我只输入 Hello
,拆分函数会进入 if(str->str != NULL)
语句。我如何阻止它使用我拥有的代码执行此操作?
编辑:还有另一个问题,如果有人不介意检查一下。 temp
只会指向 str->str
中的第一个单词。我怎样才能让它指向整个事情?
在拆分函数中的最后一个 if 块之前添加此语句
str->str = strtok(str->str," \t");
喜欢
str->str = strtok(str->str," \t");
if(str->str != NULL)
{
puts("In null if");
str->two = strtok(str->str, "");
}
你根据 "\t"
作为分隔符拆分了字符串,但你从未更改过 str->str
字符串,使用上面的代码片段它应该可以正常工作
strtok
是一个有趣的函数,它既可以修改您传递给它的字符串,又可以在内部存储有关它的信息。您应该将您的字符串传递给 strtok
一次,然后在后续调用中传递 NULL。例如,如果您的目标是简单地将字符串分解为标记(这显然是 strtok
的目的),那么类似于:
#define BUFFER_SIZE 256
int main(void) {
char *buffer = malloc(BUFFER_SIZE);
if (!buffer) {
return -1;
}
fgets(buffer, BUFFER_SIZE, stdin);
char *word;
char *ptr = buffer;
printf("Tokens: [");
while ((word = strtok(ptr, " \t\n"))) {
printf("%s, ", word);
ptr = NULL;
}
printf("]\n");
free(buffer);
}
会起作用。当我 运行 这样的代码时:
./quick
when in the fun apple orange
我得到以下结果:
Tokens: [when, in, the, fun, apple, orange, ]
重要的是我在第一次通过循环时只将buffer
指针传递给了strtok
。之后它被传递为 NULL。
我正在尝试使用 strtok()
将字符串拆分为两个标记,字符串中可能混有空格和制表符。
所以我做了这个:
struct strstr
{
char *str,
*one,
*two;
};
typedef struct strstr *STRSTR;
void split(STRSTR);
int main()
{
STRSTR str = malloc(sizeof(struct strstr));
str->str = malloc(256);
fgets(str->str, 256, stdin);
split(str);
printf("%s, %s\n", str->one, str->two);
free(str->str);
free(str);
return 0;
}
void split(STRSTR str)
{
int i;
char *temp = str->str;
while(isspace(*(str->str)))
str->str++;
str->one = strtok(str->str, " \t");
for(i = 0; i < strlen(str->one); i++)
{
if(!isspace(str->one[i]))
str->str++;
}
str->str++;
if(str->str != NULL)
{
puts("In null if");
str->two = strtok(str->str, "");
}
str->str = temp;
}
所以比如你输入Hello Earth lingss
,它会打印出Hello, Earth lingss
,这是完美的。
但是,如果我只输入 Hello
,拆分函数会进入 if(str->str != NULL)
语句。我如何阻止它使用我拥有的代码执行此操作?
编辑:还有另一个问题,如果有人不介意检查一下。 temp
只会指向 str->str
中的第一个单词。我怎样才能让它指向整个事情?
在拆分函数中的最后一个 if 块之前添加此语句
str->str = strtok(str->str," \t");
喜欢
str->str = strtok(str->str," \t");
if(str->str != NULL)
{
puts("In null if");
str->two = strtok(str->str, "");
}
你根据 "\t"
作为分隔符拆分了字符串,但你从未更改过 str->str
字符串,使用上面的代码片段它应该可以正常工作
strtok
是一个有趣的函数,它既可以修改您传递给它的字符串,又可以在内部存储有关它的信息。您应该将您的字符串传递给 strtok
一次,然后在后续调用中传递 NULL。例如,如果您的目标是简单地将字符串分解为标记(这显然是 strtok
的目的),那么类似于:
#define BUFFER_SIZE 256
int main(void) {
char *buffer = malloc(BUFFER_SIZE);
if (!buffer) {
return -1;
}
fgets(buffer, BUFFER_SIZE, stdin);
char *word;
char *ptr = buffer;
printf("Tokens: [");
while ((word = strtok(ptr, " \t\n"))) {
printf("%s, ", word);
ptr = NULL;
}
printf("]\n");
free(buffer);
}
会起作用。当我 运行 这样的代码时:
./quick
when in the fun apple orange
我得到以下结果:
Tokens: [when, in, the, fun, apple, orange, ]
重要的是我在第一次通过循环时只将buffer
指针传递给了strtok
。之后它被传递为 NULL。