【问题标题】:How to abbreviate a full name in C? [closed]如何在 C 中缩写全名? [关闭]
【发布时间】:2017-06-15 14:27:37
【问题描述】:

我试图从用户那里得到一个全名并显示他的名字缩写,就像这样:

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

【问题讨论】:

  • 我要做的第一件事是用空格字符分割名称字符串,因此您将从Edward Cantrell Cavender Davis 创建4 个字符串。将该字符串拆分为子字符串后,只需根据顺序应用您的逻辑(即第一个子字符串需要缩写,最后一个子字符串需要保留)。您不需要库来执行此操作,因为您已经在使用 &lt;string.h&gt;
  • 是我的想法,我在这里尝试这样做,如果我得到,我将发布代码。也感谢您的帮助。
  • 你的问题太宽泛了,你真的要求我们为你编码。您提出了一个很好的问题,但您的问题不够具体。
  • 你真的真的真的不应该使用gets
  • 这可能对你有帮助:stackoverflow.com/questions/9210528/…

标签: c arrays string algorithm function


【解决方案1】:

我在想是否有一些图书馆可以做到这一点

不,没有。你必须编写自己的代码来实现这一点。


我可以使用的算法如下:

  1. 查找最后一个空格(标记其索引)并提取姓氏。
  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

【讨论】:

  • 谢谢,效果很好。我是 C 新手,所以这个解决方案有点复杂,从来没有想过这个解决方案。我认为拆分所有字符串并使用其他方法,但你的更好。无论如何,+1 并投票选出最佳评论。
  • 次要:OP 的 char name[200]; ... gets(name); 暗示 name 没有 '\n',因此推荐 #define LEN 200+1)` 并删除任何尾随 '\n'
  • 感谢提醒,我将在代码中更改。
【解决方案2】:

借助名为链表的数据结构:

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

【讨论】:

    【解决方案3】:

    我觉得这里的答案并没有真正利用 C 库,所以我决定展示另一种方式。如果您是 C 新手,我真的建议您仔细阅读代码并阅读手册页(在终端中键入 ma​​n [command] 并阅读文档),了解您不了解的每个功能熟悉。具体来说,看看我在 for 循环 中对 sprintf() 的使用。理解它为什么有效是 C 语言向前迈出的一大步。我还建议阅读 Kernighan 和 Ritchie 所著的开创性书籍The C Programming Language。您不仅会成为一名更好的 C 程序员,而且总体上会成为一名更好的程序员。

    words 是一个字符串数组,其中每个字符串都是名称中的一个单词。在您的示例中,数组将是:

    words[0] = "Edward"
    words[1] = "Cantrell"
    words[2] = "Cavender"
    words[3] = "Davis\n"
    

    *注意最后一个单词末尾的换行符。 getline() 返回原始用户输入,由于用户按下回车表示输入结束,换行符继续。

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

    【讨论】:

      猜你喜欢
      • 2020-07-21
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多