问题描述:1009 说反话 (20分)
给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。
输入格式:
测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有区分)组成的字符串,单词之间用 1 个空格分开,输入保证句子末尾没有多余的空格。
输出格式:
每个测试用例的输出占一行,输出倒序后的句子。
输入样例:
Hello World Here I Come
输出样例:
Come I Here World Hello
题目很熟悉,之前在学校的oj网站刷过,是最基础的题目,但是我记得当时用的是二维数组写的,即每个单词分别保存,然后逆序输出。
一、直接用二维数组输入
代码如下:
#include<stdio.h>
int main()
{
int num=0;
char ans[90][90];
while(scanf("%s",ans[num])!=EOF)//一直输入到文件末尾
{
num++;
}
for(int i=num-1;i>=0;i--)
{
printf("%s",ans[i]);
if(i>0) printf(" ");
}
}
//这个不能直接结束while循环,要在键盘上输入Ctrl+z 再回车
二、或者用gets函数
或者用gets函数来获取字符串,gets从标准输入设备读字符串函数,其可以无限读取,不会判断上限,以回车结束读取。而空格不会让其结束。
从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串。
代码可以这样写
(当然也可以把最后一种方法用gets函数获取输入就行):
/*第二种做法是把这个字符串存进一个字符数组中*/
# include<stdio.h>
#include<string.h>
int main()
{
char str[90];
gets(str);
int len=strlen(str),r=0,h=0;//r为行,h 为列
char ans[90] [90];
for(int i=0;i<len;i++)
{
if(str[i]!=' ')
{
ans[r][h++]=str[i];
}
else
{
ans[r][h]='\0';
r++;
h=0;
}
}
for(int i=r;i>=0;i--)
{
printf("%s",ans[i]);
if(i>0) printf(" ");
}
return 0;
}
三、通过scanf格式化输入获取
第三种方法,是通过%[]格式化来读取stdin流。
例如
scanf("%[abc]",str);
//只要读到不是中括号里的集合则结束,即这里只能读abc三种字符
//重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写字符时,应该分别说明大、小写字母。
而符号^代表取补集,例如:
scanf("%[^\n]");
//表明除了换行符\n都可以读取,也就是读到换行符就结束。
如果直接scanf("%s",str),这样如果读到空格就会结束的,题目要求是输入一个句子,单词和单词之间是空格隔开的,所以这样是读取不到的。
所以第三种方法的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char s[81];
scanf("%[^\n]",s);
int i;
int length = strlen(s);
for (i = length-1; i >=0; i--)
{
if (s[i] == ' ')
{
printf("%s",&s[i+1]);
printf(" ");
s[i] = '\0';
}
if (i == 0)
{
printf("%s", &s[i]);
}
}
return 0;
}
/*
1、主要是关于printf("%s",&a[i]);应用的解释:
%s是输出指向字符指针对应的字符串,以\0作为结束符.
&a[i]的意思是取str字符数组的第i个元素的地址,
整句话的意思是以a字符数组的第i个元素为起始元素开始打印字符串,
直到遇到\0.(所以a[i]='\0'的不能遗漏,否则可能会因为没有结束的'\0'而多输出一些乱码或是字符串。)
2、关于gets()函数是向字符数组输入一个字符串,当遇到回车符时结束输入,
系统会自动在所有有效字符后加上结束符‘\0’,所以实际长度+1。但是在C++11中,
GETS已经被全面取缔,所以在PTA的C++类型编译中
并不适用,但是在我在c语言gcc版本中是通过了的。
用以上的输入方法时,也需要注意在最后加上A[U]='\0'*/