2017-06-15 20 views
1

我想从用户那里得到一个全名,并显示他的名字缩写,这样的事情:如何在C中缩写全名?

“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

我会做的第一件事是用空格字符拆分名称字符串,所以你会从'Edward Cantrell Cavender Davis'创建4个字符串。一旦将该字符串拆分为子字符串,只需根据顺序应用您的逻辑(即第一个子字符串需要缩写,最后一个子字符串需要保留)。你不需要一个库来做到这一点,因为你已经在使用'' –

+0

是我的想法,我试图在这里做,如果我得到了,我会发布代码。感谢您的帮助。 – Monteiro

+4

你的问题太宽泛,你真的要求我们为你编码。你提出了一个很好的问题,但是你的问题还不够具体。 – Stargateur

回答

2

我在想,如果有一些库,这是否

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


的算法,我可以用如下:

  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

+1

谢谢,它工作完美。我是C新手,所以这个解决方案有点复杂,从来不会想到这个。我认为把所有的字符串分开并使用其他方法,但是你的更好。无论如何,+1和最佳评论投票。 – Monteiro

+1

轻微:OP的char名称[200]; ...获得(名称);'暗示没有''\ n''的'name',所以推荐'#define LEN'200 + 1)'并且关掉任何尾随的''\ n'。 – chux

+0

感谢提醒,我将在代码中改变这一点。 – Monteiro

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

我觉得这里的答案,没有真正充分利用C库多,所以我决定展示另一种方式。如果你是C的新手,我真的推荐阅读代码并阅读手册页(在终端中键入man [命令]并阅读文档),以了解您不熟悉的每个函数。具体来说,看看我使用sprintf()在for循环。理解为什么这是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); 
}