我正在尝试从用户那里获取一个全名并显示他的名字缩写,如下所示:
“Edward Cantrell Cavender Davis” --> Name the user entered
"DAVIS, E. C. C.” -- Name abbreaviated
问题在于我不知道如何做到这一点,在C中是新手,我在想是否有一些库可以做到这一点。
用户可以输入的最大大小名称是200
,我需要通过一个函数检查它并显示缩写的名称。
我的代码:(我被困在这里)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void name_abbreviated (char name[200]) {
}
int main() {
char name[200];
printf("Type a full name : ");
gets(name);
name_abbreviated(name);
}
答案 0 :(得分:2)
我在想是否有一些库可以做到这一点
不,没有。您必须编写自己的代码才能实现此目的。
我可以使用的算法如下:
name
,直到空格(您有索引)
已经)。每当你遇到一个空间,请存储首字母
将这个词放入缓冲区。代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 200
void name_abbreviated (char name[]) {
//printf("|%s|\n", name);
char last_name[20];
int j = 0, last_space_idx;
for(int i = strlen(name) - 1; i >= 0; --i)
{
if(name[i] == ' ')
{
last_space_idx = i;
while(name[i])
last_name[j++] = name[++i];
last_name[j] = '\0';
break;
}
}
//printf("|%s|\n", last_name);
char rest_name[15];
rest_name[0] = name[0];
rest_name[1] = '.';
rest_name[2] = ' ';
j = 3;
for(int i = 3; i < last_space_idx; ++i)
{
if(name[i] == ' ')
{
rest_name[j++] = name[i + 1];
rest_name[j++] = '.';
rest_name[j++] = ' ';
}
}
rest_name[j - 1] = '\0';
//printf("|%s|\n", rest_name);
printf("%s, %s\n", last_name, rest_name);
}
int main() {
char name[LEN];
printf("Type a full name : ");
fgets(name, LEN, stdin);
printf("\n");
name_abbreviated(name);
return 0;
}
输出:
Type a full name :
Davis, E. C. C.
或者,如果您愿意,请参阅 Live demo 。
答案 1 :(得分:1)
借助名为链表的数据结构:
struct name {
char string[200];
struct name *next;
}
void name_abbreviated(char *input)
{
struct name first;
struct name *p = &first;
struct name *last;
int i = 0;
while (sscanf(input, "%199s", p->string) != EOF) {
i++;
last = p; // keep pointer to possible last name
input += strlen(p->string) + 1; // advance input, +1 for space
p->next = malloc(sizeof(struct name));
p = p->next;
}
// print last name
printf("%s,", last->string);
// print rest
int j;
p = &first;
for (j = 0; j < i - 1; j++) {
printf(" %c.", p->string[0]);
p = p->next;
}
printf("\n");
// free malloced memories
struct name *prev = NULL;
p = first.next;
while (p) {
prev = p;
p = p->next;
free(prev);
}
}
int main()
{
char name[200];
printf("Type a full name: ");
fgets(name, 200, stdin);
name_abbreviated(name);
}
答案 2 :(得分:1)
我觉得这里的答案并没有真正利用C库,所以我决定以另一种方式展示。如果您是C新手,我真的建议您浏览代码并阅读手册页(在终端输入 man [command] 并阅读文档)这里的每个函数都不是熟悉。具体来说,看看我在 for循环中对sprintf()的使用。了解其工作原理是C中向前迈出的一大步。我还建议您阅读Kernighan和Ritchie的开创性着作 The C Programming Language 。你不仅会成为一个更好的C程序员,而且会成为一个更好的程序员。
单词是一个字符串数组,其中每个字符串都是名称中的单词。在您的示例中,数组将是:
words[0] = "Edward"
words[1] = "Cantrell"
words[2] = "Cavender"
words[3] = "Davis\n"
*注意最后一个单词末尾的新行字符。 getline()返回原始用户输入,并且由于用户按Enter键表示输入结束,新行字符将继续执行。
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define LEN 200
void name_abbreviated(char *name) {
char tmp[LEN+1], abbr[LEN], *words[LEN], *token;
int i = 0;
strncpy(tmp, name, LEN);
token = strtok(tmp, " ");
while (token) {
words[i++] = token;
token = strtok(NULL, " ");
}
// remove '\n' from last word
words[i-1][strlen(words[i-1]) - 1] = '\0';
sprintf(abbr, "%s, ", words[i-1]);
for (int j = 0; j < i - 1; j++)
sprintf(abbr + strlen(abbr), "%c. ", words[j][0]);
puts(abbr);
}
int main(void) {
char *name = NULL;
char *abbr;
size_t linecap = LEN;
printf("Type a full name : ");
getline(&name, &linecap, stdin);
name_abbreviated(name);
}