如何在C中缩写全名?

时间:2017-06-15 14:27:38

标签: c arrays string algorithm function

我正在尝试从用户那里获取一个全名并显示他的名字缩写,如下所示:

“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);
}

3 个答案:

答案 0 :(得分:2)

  

我在想是否有一些库可以做到这一点

不,没有。您必须编写自己的代码才能实现此目的。

我可以使用的算法如下:

  1. 找到最后一个空格(标记其索引)并提取姓氏。
  2. 循环遍历name,直到空格(您有索引) 已经)。每当你遇到一个空间,请存储首字母 将这个词放入缓冲区。
  3. 代码:

    #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);
}