在 C 中不使用 strtok 来提取事件的更简单方法
Simpler way to extract occurrences without using strtok in C
我正在尝试从给定字符串中提取第一个逗号前后的字符串。但是,我觉得一定有比下面的方法更好的方法,也许我什至不需要 strdup
调用。谢谢
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int extract_names(const char *str)
{
char *name, *last, *p1, *p2, *p3;
name = strdup(str);
last = strdup(str);
p1 = strchr(name, ',');
if (p1)
{
*p1 = '[=10=]';
printf("%s\n", name);
}
p2 = strchr(last, ',');
p2++;
if (p2)
{
p3 = strpbrk(p2 + 1, " [=10=]");
if (p3)
*p3 = '[=10=]';
printf("%s\n", p2);
}
free(name);
free(last);
return 0;
}
int main()
{
// strings should at least contain last,name.
// but can contain several words
const char *str1 = "jones,bob age,12";
extract_names(str1);
const char *str2 = "smith,peter";
extract_names(str2);
return 0;
}
输出
jones
bob
smith
peter
既然你显然在努力学习,我只会给你一些指导,而不是 "better working solution"。
strdup
在这里是一个有用的想法。正如您所做的那样,它允许您覆盖字符串(const char *str
是 "readonly")。
这个组合:
p2 = strchr(last, ',');
p2++;
if (p2) {
错了。调用后 p2
等于 return 值。如果你在 if
之前推进它,你就没有测试任何东西(如果 NULL 是 returned,那么当你测试它时它是 1)。
不需要两次 strdup
,也不需要搜索两次。 p1
已经指向 name
中的正确位置,您可以将其用于其余的逻辑。
使用strchr
求出姓氏和名字的界限。然后,您可以使用 printf
中的精度说明符来仅打印您感兴趣的字符串部分。
例如:
int extract_names(const char *str)
{
const char *comma = strchr(str, ',');
const char *name_end = strchr(str, ' ');
/* name ends at space or end of string */
if (!name_end) {
name_end = str + strlen(str);
}
/* print last name */
printf("%.*s\n", (comma - str), str);
/* print first name */
printf("%.*s\n", name_end - comma, comma + 1);
return 0;
}
我正在尝试从给定字符串中提取第一个逗号前后的字符串。但是,我觉得一定有比下面的方法更好的方法,也许我什至不需要 strdup
调用。谢谢
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int extract_names(const char *str)
{
char *name, *last, *p1, *p2, *p3;
name = strdup(str);
last = strdup(str);
p1 = strchr(name, ',');
if (p1)
{
*p1 = '[=10=]';
printf("%s\n", name);
}
p2 = strchr(last, ',');
p2++;
if (p2)
{
p3 = strpbrk(p2 + 1, " [=10=]");
if (p3)
*p3 = '[=10=]';
printf("%s\n", p2);
}
free(name);
free(last);
return 0;
}
int main()
{
// strings should at least contain last,name.
// but can contain several words
const char *str1 = "jones,bob age,12";
extract_names(str1);
const char *str2 = "smith,peter";
extract_names(str2);
return 0;
}
输出
jones
bob
smith
peter
既然你显然在努力学习,我只会给你一些指导,而不是 "better working solution"。
strdup
在这里是一个有用的想法。正如您所做的那样,它允许您覆盖字符串(const char *str
是 "readonly")。
这个组合:
p2 = strchr(last, ',');
p2++;
if (p2) {
错了。调用后 p2
等于 return 值。如果你在 if
之前推进它,你就没有测试任何东西(如果 NULL 是 returned,那么当你测试它时它是 1)。
不需要两次 strdup
,也不需要搜索两次。 p1
已经指向 name
中的正确位置,您可以将其用于其余的逻辑。
使用strchr
求出姓氏和名字的界限。然后,您可以使用 printf
中的精度说明符来仅打印您感兴趣的字符串部分。
例如:
int extract_names(const char *str)
{
const char *comma = strchr(str, ',');
const char *name_end = strchr(str, ' ');
/* name ends at space or end of string */
if (!name_end) {
name_end = str + strlen(str);
}
/* print last name */
printf("%.*s\n", (comma - str), str);
/* print first name */
printf("%.*s\n", name_end - comma, comma + 1);
return 0;
}