用 strtok_r 分隔名字和中间名以及姓氏
Separate first name with middle name and last name with strtok_r
所以我遇到了一些与我之前在 C 编程中的探索相关的问题。这次是关于如何使用 strtok_r
或 strtok
将名称与 /etc/passwd
文件分开。交易是我想将用户名分为两部分,第一部分是名字和中间名(假设他们有一个),第二部分是姓氏。但我找不到正确分隔名称的方法。我让它在第一部分使用他们的名字,但后来中间名附加到姓氏。
/etc/passwd
行如下所示:
s214907:x:1240:1251:Jonas Villa,,,:/home/s214907:/bin/bash
s212167:x:1297:1306:Konstantina Pavlova Rusenkova,,,:/home/s212167:/bin/bash
我得到的示例:
[Konstantina] [Pavlova Ruskenova]
我希望它如何打印的示例:
[Konstantina Pavlova] [Ruskenova]
到目前为止,这是我的代码:
char line[256], words[20];
char *mname, *tmp, *uid, *sp, *lname, *uname, *name, *fname, *tmps;
int bindex=0, index, cnt =0, count;
char *rest = NULL;
FILE*fp = fopen("/etc/passwd","r");
size_t len = 0;
char *next = NULL;
while(fgets(line,256,fp)!=NULL)
{
sp = strtok(line, ":");
tmp = strtok(NULL, ":");
uid = strtok(NULL, ":");
tmp = strtok(NULL, ":");
name = strtok(NULL, ":,");
if(atoi(uid) > 999)
{
for(tmps = strtok_r(name, " ", &rest);
tmps != NULL;
tmps = strtok_r(NULL, ",", &rest)) {
tmps = strtok(tmps, ",");
printf("[%s]\n", tmps);
}
}
cnt++;
}
fclose(fp);
您使用 strtok_r
或 strtok
拆分名称的方法无效。
将(完整)名称标记化后,您会得到:
name="Konstantina Pavlova Rusenkova"
您通过 name = strtok(NULL, ":,");
获得此名称。因此它不能包含任何 ','
。如果有 ','
字符串就会在那里被截断。
使用定界符 ','
的任何进一步标记化无法获得任何有用的结果,除了 return 完整的字符串本身。
这意味着在你的内部循环中 tmps = strtok(tmps, ",");
不会做任何事情。
我添加了一些印刷品:
printf("name=%s\n",name);
if(atoi(uid) > 999)
{
for(tmps = strtok_r(name, " ", &rest);
tmps != NULL;
tmps = strtok_r(NULL, ",", &rest))
{
printf("tmps:%s\n", tmps);
tmps = strtok(tmps, ",");
printf(" [%s]\n", tmps);
}
}
结果是:
name=Konstantina Pavlova Rusenkova
tmps:Konstantina
[Konstantina]
tmps:Pavlova Rusenkova
[Pavlova Rusenkova]
第二个打印显示您输入 tmps=strtok(tmps,",");
的内容。如上所述,分隔符永远不会存在,将所有内容都留在第二个括号中。
一般来说,strtok
and friends 对拆分名字没什么用。如果将字符串分开,则没有两个名字在一起。空格替换为 [=27=]
.
相反,您可以简单地搜索最后一个空格并在那里拆分:
if(atoi(uid) > 999)
{
char *first = name;
char *last = strrchr(name,' ');
if (last != NULL)
{
*last = 0;
last++;
printf("[%s] [%s]\n", first, last);
}
}
这将得到
name=Konstantina Pavlova Rusenkova
[Konstantina Pavlova] [Rusenkova]
它仍然适用于只有 1 个名字的名字:
name=James Kirk
[James] [Kirk]
如果一共只有一个名字,你需要稍微调整一下。
注:
如果出于某种原因你坚持使用 strtok
来分割名称,你需要使用分隔符 ' '
然后将第一个和第二个子字符串粘合在一起。
这看起来像这样:
if(atoi(uid) > 999)
{
for(tmps = strtok_r(name, " ", &rest);
tmps != NULL;
tmps = strtok_r(NULL, " ", &rest))
{
printf("tmps:%s\n", tmps);
printf(" [%s]\n", tmps);
}
}
有输出
name=Konstantina Pavlova Rusenkova
tmps:Konstantina
[Konstantina]
tmps:Pavlova
[Pavlova]
tmps:Rusenkova
[Rusenkova]
所以我遇到了一些与我之前在 C 编程中的探索相关的问题。这次是关于如何使用 strtok_r
或 strtok
将名称与 /etc/passwd
文件分开。交易是我想将用户名分为两部分,第一部分是名字和中间名(假设他们有一个),第二部分是姓氏。但我找不到正确分隔名称的方法。我让它在第一部分使用他们的名字,但后来中间名附加到姓氏。
/etc/passwd
行如下所示:
s214907:x:1240:1251:Jonas Villa,,,:/home/s214907:/bin/bash
s212167:x:1297:1306:Konstantina Pavlova Rusenkova,,,:/home/s212167:/bin/bash
我得到的示例:
[Konstantina] [Pavlova Ruskenova]
我希望它如何打印的示例:
[Konstantina Pavlova] [Ruskenova]
到目前为止,这是我的代码:
char line[256], words[20];
char *mname, *tmp, *uid, *sp, *lname, *uname, *name, *fname, *tmps;
int bindex=0, index, cnt =0, count;
char *rest = NULL;
FILE*fp = fopen("/etc/passwd","r");
size_t len = 0;
char *next = NULL;
while(fgets(line,256,fp)!=NULL)
{
sp = strtok(line, ":");
tmp = strtok(NULL, ":");
uid = strtok(NULL, ":");
tmp = strtok(NULL, ":");
name = strtok(NULL, ":,");
if(atoi(uid) > 999)
{
for(tmps = strtok_r(name, " ", &rest);
tmps != NULL;
tmps = strtok_r(NULL, ",", &rest)) {
tmps = strtok(tmps, ",");
printf("[%s]\n", tmps);
}
}
cnt++;
}
fclose(fp);
您使用 strtok_r
或 strtok
拆分名称的方法无效。
将(完整)名称标记化后,您会得到:
name="Konstantina Pavlova Rusenkova"
您通过 name = strtok(NULL, ":,");
获得此名称。因此它不能包含任何 ','
。如果有 ','
字符串就会在那里被截断。
使用定界符 ','
的任何进一步标记化无法获得任何有用的结果,除了 return 完整的字符串本身。
这意味着在你的内部循环中 tmps = strtok(tmps, ",");
不会做任何事情。
我添加了一些印刷品:
printf("name=%s\n",name);
if(atoi(uid) > 999)
{
for(tmps = strtok_r(name, " ", &rest);
tmps != NULL;
tmps = strtok_r(NULL, ",", &rest))
{
printf("tmps:%s\n", tmps);
tmps = strtok(tmps, ",");
printf(" [%s]\n", tmps);
}
}
结果是:
name=Konstantina Pavlova Rusenkova
tmps:Konstantina
[Konstantina]
tmps:Pavlova Rusenkova
[Pavlova Rusenkova]
第二个打印显示您输入 tmps=strtok(tmps,",");
的内容。如上所述,分隔符永远不会存在,将所有内容都留在第二个括号中。
一般来说,strtok
and friends 对拆分名字没什么用。如果将字符串分开,则没有两个名字在一起。空格替换为 [=27=]
.
相反,您可以简单地搜索最后一个空格并在那里拆分:
if(atoi(uid) > 999)
{
char *first = name;
char *last = strrchr(name,' ');
if (last != NULL)
{
*last = 0;
last++;
printf("[%s] [%s]\n", first, last);
}
}
这将得到
name=Konstantina Pavlova Rusenkova
[Konstantina Pavlova] [Rusenkova]
它仍然适用于只有 1 个名字的名字:
name=James Kirk
[James] [Kirk]
如果一共只有一个名字,你需要稍微调整一下。
注:
如果出于某种原因你坚持使用 strtok
来分割名称,你需要使用分隔符 ' '
然后将第一个和第二个子字符串粘合在一起。
这看起来像这样:
if(atoi(uid) > 999)
{
for(tmps = strtok_r(name, " ", &rest);
tmps != NULL;
tmps = strtok_r(NULL, " ", &rest))
{
printf("tmps:%s\n", tmps);
printf(" [%s]\n", tmps);
}
}
有输出
name=Konstantina Pavlova Rusenkova
tmps:Konstantina
[Konstantina]
tmps:Pavlova
[Pavlova]
tmps:Rusenkova
[Rusenkova]