所以我正在做一个小项目,而我想获取模拟数据并将其分离为结构。但是我想到的是具有多个姓氏和/或姓氏的人的问题。
我想像您一样写名字(例如“ Michael ”),并用所有大写字母写姓(例如“ JAMESON ”)。
但是,如果我读到 Michael Daniel VAN DOORNE 之类的名字怎么办?我不知道如何分隔“ Michael Daniel ” “”作为名字,“ VAN DOORNE ”作为姓氏。我试图通过以第一个大写字母开头来分隔,但我当然也将某人的名字中的第一个字母大写。
示例:
我想阅读 Michael Daniel VAN DOORNE ,并分别将其分为“ Michael Daniel ”和“ VAN DOORNE ”。姓
sscanf(buffer, "%s %s", firstName, lastName);
那自然不会起作用。但是我有点想提出一种解决方案,以解决具有多个名字和姓氏的模拟名字。
答案 0 :(得分:5)
由于您似乎可以完全控制数据,因此我建议您使用另一种方法:
在姓氏和姓氏之间的特定分隔符。然后,您不再依赖于区分大小写,尤其是另一个答案中出现的单个字符名称问题不再是问题。
分隔符应该是一个永远不会出现的名称,例如制表符(与空格相反),#
,'|',...,甚至逗号或分号也可以。 ,尽管句号可能以缩写名称出现,因此不应使用。
答案 1 :(得分:1)
因此,要知道它是名字的一部分还是姓氏是一个挑战,但是从声音的角度来看,您可以控制数据,因此可以小写名字并大写名字或使用其他方法。
分解字符串,使用strtok
相对容易。
做出一些假设,即您正在逐行读取名称并将其填充到buffer
中。
使用strtok
将buffer
分解为“名称”。
char *token
token = strtok(buffer, " "); //note the second parameter is what you want to parse the array by
while(token != NULL)
{
if(isupper(token[0]))
//store that token into your struct (first or last name) allow for multiple
else
//store into the other
token = strtok(NULL, " "); //keep looping on string for names
}
答案 2 :(得分:0)
strspn
和strcspn
可用于遍历字符串并找到第一个大写单词。
#include <stdio.h>
#include <string.h>
int main( void) {
char line[] = "Michael Daniel VAN DOORNE";
char upper[] = "ABCDEFGHIJKLMNOPQURSTUVWXYZ";
int last = 0;
int start = 0;
int check = 0;
do {
last = start + check;
check += start + 1;
start = strspn ( line + check, upper);//span of characters that are uppercase
if ( ' ' != line[start + check]) {//is the next character a space
start = strcspn ( line + check, " ");//find the space
if ( line[start + check]) {//not the terminatins zero
start++;
}
}
} while ( line[start + check] && ' ' != line[start + check]);
printf ( "%s\n", &line[last]);
return 0;
}
答案 3 :(得分:0)
假设姓氏始终用大写字母书写,请从末尾开始读取字符串,看看什么时候使用小写字母。
int i=strlen(buffer)-1;
while(!islower(buffer[i]) && i>0)
i--;
strncpy(firstName,buffer,i+1);
strcpy(lastName,&buffer[i+2]);
答案 4 :(得分:0)
这是另一种解决方案。请阅读直到有两个大写字母或一个大写字母和一个空格为止。然后使用指针算法填充名字和姓氏。
char name[] = "Michael Daniel VAN DOORNE";
char *p = name;
char firstname[100] = { 0 };
char lastname[100] = { 0 };
while (*p)
{
if (isupper(p[0]) && (isupper(p[1]) || p[1] == ' '))
{
strcpy(lastname, p);
strncpy(firstname, name, p - name - 1);
break;
}
p++;
}
答案 5 :(得分:0)
如果您使用的是ASCII,这是一个特定于字符集的技巧,可以帮助您:
#define TWOUPPER(c0, c1) (!((c0) & 32) && !((c1) & 32))
这对单个字符的姓氏也将起作用,因为空字符将不能通过第5位检查,并且由于以下空格将无法通过测试,因此单个字符的中间名将不会被用作姓氏。
通过比较字符串中的每两个字符并停止匹配,为我使用以下测试用例:
char test1[100] = "Otto VON BISMARK",
test2[100] = "Johannes Diderik VAN DER WAALS",
test3[100] = "Vincent VAN GOGH",
test4[100] = "Govind A B C D P"; // Only the "P" is counted as the last name here