这是以前写的一个小东西,针对一个公司的某个面实题。跟这个差不多,但没有处理最后的标点符号。要处理也容易,加上一个判断就行了。
先来看一个用C语言写的程序,程序的功能是将输入的字符串以单词为单位倒序输出,比如输入“hello, world!”,那么程序输出“world!, hello”:
#include <stdio.h>
#include <string.h>
int main()
{int i=0;
char flag='y';
char str[80][100]={"\0"};
while(flag=='y'||flag=='Y')
{
i=0;
printf("Input the string:\n");
while(1)
{
scanf("%s",str[i]);
i++;
if(getchar()==10)
break;
}
i--;
for( ;i>=0;i--)
printf("%s ",str[i]);
printf("\n");
printf("Will you continue ? ( y / n ) :");
flag=getchar();
}
return 0;
}
评价:根据scanf函数的特性,以空格可以作为字符串输入的结束,所以采用了一个二维数组,以回车作为输入串的结束。这样容易实现,但比较浪费空间。假设最长的单词长度为20,而最短的单词长度只有1,那么显然,存储短单词的时候必然带来空间的浪费。
改进1:
#include <stdio.h>
#include <string.h>
int main()
{int i=0,j=0;
char flag='y';
char str[100]="\0";
char *p=str;
int len[80]={0};
while(flag=='y'||flag=='Y')
{
str[0]='\0';
i=0;
j=0;
printf("Input the string:\n");
while(1)
{
p=str+strlen(str);
scanf("%s",p);
len[j]=strlen(p);
j++;
if(getchar()==10)
break;
}
j--;
for( ;j>=0;j--)
{
for(i=0;i<len[j];i++)
printf("%c",p[i]);
p=p-len[j-1];
printf(" ");
}
printf("\n");
printf("Will you continue ? ( y / n ) :");
flag=getchar();
}
return 0;
}
评价:这里用一个一维数组来代替上面的二维数组,并引入另一个数组来记录每个单词的长度,引入一个指针指向存储数组的末尾,当有新单词输入时,从当前字符串的末尾开始存储。当输出时,首先得到单词的长度,然后输出。这解决了空间的浪费。因为两个一维数组要比一个二维数组省得多。而且存储字符串的数组中的字符一个紧接一个,中间没有空格。但这里有个小问题,就是如果输入两个空格,然后回车,那么程序不能认为整个字符串的输入结束,必须等待至少一个字符,第二次回车程序才能判断输入结束。这是scanf函数的弱点带来的。
改进2:
#include <stdio.h>
#include <string.h>
int main()
{
int i=0,j=0,len[10]={0};
char tmp,flag='y';
char str[100]="\0",*p;
p=str;
while(flag=='y'||flag=='Y')
{
for(i=0;i<100;i++)
str[i]='\0';
i=j=0;
p=str;
printf("Input the string:\n");
while(1)
{
tmp=getchar();
if(tmp==10)
break;
if(tmp==32)
{
len[j]=strlen(p);
i=0;
j++;
p=str+strlen(str);
continue;
}
p[i]=tmp;
i++;
}
len[j]=strlen(p);
for(;j>=0;j--)
{
i=0;
while(i<len[j])
{
printf("%c",p[i]);
i++;
}
printf(" ");
p=p-len[j-1];
}
printf("\n");
printf("Will you continue ? ( y / n ) : ");
flag=getchar();
}
return 0;
}
评价:这里不用scanf函数接受字符串,而是用getchar函数逐一结束字符,当有回车,立即结束输入。
教训:
1、最外层while循环如果不加赋值语句"p=str;"则出现段错误;
2、如果用scanf("%c",flag);语句来接受flag的值,那么必须在后面加上 一个getchar();语句来屏蔽回车,否则回车作为内层循环的结束符。