2016-07-24 45 views
3

我正在尝试开发一个基本程序,它以您的名字和标准格式提供输出。问题是我希望用户有一个不添加中间名的选项。以标准格式打印名称

例如:卡尔米娅奥斯汀给我C.M.奥斯汀,但即使输入是卡尔奥斯汀,它也应该给我C.奥斯汀,而不询问用户是否有中间名。 那么,有没有一种方法或功能可以自动检测?

#include <stdio.h> 

int main(void) { 
    char first[32], middle[20], last[20]; 

    printf("Enter full name: "); 
    scanf("%s %s %s", first, middle, last); 
    printf("Standard name: "); 
    printf("%c. %c. %s\n", first[0], middle[0], last); 

    return 0; 
} 

回答

7

上述代码,scanf("%s %s %s", first, middle, last);预计3个部分键入,并且会等到用户键入他们。

你想读一个线路输入与fgets()和扫描,对于名称部分与sscanf并指望有多少部分被转换:

#include <stdio.h> 

int main(void) { 
    char first[32], middle[32], last[32]; 
    char line[32]; 

    printf("Enter full name: "); 
    fflush(stdout); // make sure prompt is output 
    if (fgets(line, sizeof line, stdin)) { 
     // split the line into parts. 
     // all buffers have the same length, no need to protect the `%s` formats 
     *first = *middle = *last = '\0'; 
     switch (sscanf(line, "%s %s %[^\n]", first, middle, last)) { 
     case EOF: // empty line, unlikely but possible if stdin contains '\0' 
     case 0: // no name was input 
      printf("No name\n"); 
      break; 
     case 1: // name has a single part, like Superman 
      printf("Standard name: %s\n", first); 
      strcpy(last, first); 
      *first = '\0'; 
      break; 
     case 2: // name has 2 parts 
      printf("Standard name: %c. %s\n", first[0], middle); 
      strcpy(last, middle); 
      *middle = '\0'; 
      break; 
     case 3: // name has 3 or more parts 
      printf("Standard name: %c. %c. %s\n", first[0], middle[0], last); 
      break; 
     } 
    } 
    return 0; 
} 

注意,名称可以在现实生活中多一点多才多艺:想想外国人的多字节字符,甚至简单地称为比尔盖茨(Bill Gates)。上面的代码处理后者,但不是这一个:Éléonore de Provence,亨利三世,英格兰国王,1223年轻的妻子 - 1291

+0

唯一problemI SE在这个代码是语义@chqrlie。如果该人没有中间名,但只输入姓氏和名字,那么姓氏的含义被解释为“中间”。 – user3078414

+0

@ user3078414:我不确定你在评论中的含义。如果用户只输入一个只有2个部分的名字,那么'sscanf()'只能转换'first'和'middle',并且*标准名称*会被打印为'first'和full'middle'的首字母,这真的是最后一个名字。重命名这3个数组'part1','part2'和'part3'将减少潜在的混淆。 – chqrlie

+0

感谢您的回应,@ chqrlie。我正在考虑可能组织数据并准备将其复制到任何数据库所需的代码。我不相信有人需要这样的代码来提供'printf()'。 ( - : – user3078414

0

您可以使用isspace,并在名称查找空间:

#include <stdio.h> 
#include <ctype.h> 

int main(void) 
{ 
    char first[32], middle[32], last[32]; 
    int count=0; 
    int i = 0; 
    printf("Enter full name: "); 
    scanf(" %[^\n]s",first); 
    for (i = 0; first[i] != '\0'; i++) { 
     if (isspace(first[i])) 
      count++; 
    } 
    if (count == 1) { 
     int read = 0; 
     int k=0; 
     for (int j = 0; j < i; j++) { 
      if (isspace(first[j])) 
       read++; 
      if (read > 0) { 
       last[k]=first[j]; 
       k++; 
      } 
     } 
     last[k+1] = '\0'; 
    } 
    printf("Standard name: "); 
    printf("%c. %s\n", first[0], last); 

    return 0; 
} 

测试

Enter full name: Carl Austin 
Standard name: C. Austin 
+0

我想你也应该测试两个名字会发生什么 – usr2564301

+0

你的'scanf'模式中存在一个“s”,但也许最好是使用'fgets'。 – anatolyg