gpt4 book ai didi

c - 使用 strtok_r 将名字与中间名和姓氏分开

转载 作者:行者123 更新时间:2023-11-30 16:12:04 30 4
gpt4 key购买 nike

所以我遇到了一些与我之前的 C 编程探索相关的问题。这次介绍如何使用 strtok_rstrtok 将名称与 /etc/passwd 文件分开。协议(protocol)是我想将用户名分成两部分,第一部分是名字和中间名(假设他们有一个),第二部分是姓氏。但我找不到正确分隔名称的方法。我在第一部分中使用了他们的名字,但随后中间名附加到了姓氏上。

/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_rstrtok 分割名称的方法不起作用。

对(完整)名称进行标记后,您将得到:

name="Konstantina Pavlova Rusenkova"

您可以通过 name = strtok(NULL, ":,"); 获取此名称。因此它不能包含任何','。如果有 ',' 字符串就会在那里被截断。

使用分隔符 ',' 进行任何进一步的标记化都无法获得任何有用的结果,除非返回完整的字符串本身。

这意味着在您的内部循环中 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和 friend 对于分割名称没有什么用处。如果将字符串分开,则不会留下两个名字在一起。空格被 \0 替换。

相反,您可以简单地搜索最后一个空格并在那里拆分:

    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 将名字与中间名和姓氏分开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58432543/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com