我有以下问题: -
编写一个程序,其中输入名字和姓氏 用户并显示姓氏,逗号和第一个首字母,然后是 一段时间:
用户的输入可能在名字前包含额外的空格, 在名字和姓氏之间,以及在姓氏之后。
我为此编写了代码:
#include <stdio.h>
#include<stdlib.h>
int main(void)
{
int i=0,j=0;
char name[100];
gets(name);
while( name[i] == ' ' || name[i] == '\t' )
i++;
while( *(name+i) != ' ' && *(name+i)!= '\t' )
i++;
while(name[i] == ' '|| name[i] == '\t')
i++;
while( *(name+i) != ' ' && *(name+i) != '\t' && *(name+i) != '\0' )
putchar(name[i++]);
putchar(',');
while( name[j] == ' '|| name[j] == '\t' )
j++;
while( *(name+j) != ' ' && *(name+j) != '\t' )
{
putchar(name[j++]);
break;
}
putchar('.');
return 0;
}
虽然它有效,但似乎有些不可接受。我怎么能改进呢?
答案 0 :(得分:2)
避免使用gets()
并使用fgets()
。
从手册页:
BUGS
永远不要使用gets()。因为在不事先知道数据的情况下无法判断get()将读取多少个字符,并且因为gets()将继续存储超出缓冲区末尾的字符,所以使用它是非常危险的。它已被用来打破计算机安全。请改用fgets()。
修改强>
您可以使用ctype.h中的isalpha,isspace函数来最小化代码。
isspace() :
检查空格字符。在“C”和“POSIX”语言环境中,它们是:space,form-feed('\ f'),换行符('\ n'),回车符('\ r'),
水平制表符('\ t')和垂直制表符('\ v')。
isalpha() :
检查字母字符;在标准的“C”语言环境中,它相当于(isupper(c)|| islower(c))。在某些地区,可能会有
isalpha()的其他字符是真正的字母,既不是大写也不是小写。
您可以使用此重构代码或代码的任何部分。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_LENGTH 100
int main(void)
{
int i=0,j=0;
char name[MAX_LENGTH];
fgets(name,MAX_LENGTH,stdin); //instead of gets(name);
for(i=0;i<strlen(name) ;i++) //loop to capture initial ,after this you have initial name[i]
if(isalpha(name[i]))
break;
for(j=i;j<strlen(name);j++) //loop to find start of last name
if(isspace(name[j]))
if(isalpha(name[j+1]))
break;
for(j=j+1;j<strlen(name);j++) //loop to print last name on screen
if(isalpha(name[j]))
putchar(name[j]);
else
break;
putchar(',');
putchar(name[i]); //print initial
putchar('.');
printf("\n");
return 0;
}
答案 1 :(得分:1)
你可以使用sscanf压缩它:
#define MAX_LENGTH 100
...
char name[MAX_LENGTH];
char surname[MAX_LENGTH];
char firstname[MAX_LENGTH];
fgets( name, MAX_LENGTH, stdin );
if ( sscanf( name, "%s %s", firstname, surname ) == 2 )
{
printf( "%s, %c.\n", surname, firstname[0] );
}