这一chapter主要是利用a+b这样一个很简单的入门练习训练基本的输入输出,
比如:最基本的单个输入输出、EOF输入、N组输入、特殊标记结束、输入的变化还有特殊的输出格式的考察。
一、输入
1、单个输入
最简单,不做代码示例
2、以EOF结束输入
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include
int main()
{
int a,b;
while(scanf("%d%d",&a,&b)!=EOF)
printf("%d\n",a+b);
return 0;
}
最重要的是while一句:while(scanf("%d",&n)!=EOF)或 while (cin>>n)
3、N组输入
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include
using namespace std;
int main()
{
int n, a, b;
scanf("%d", &n);
while(n--)
{
scanf("%d%d", &a, &b);
printf("%d\n", a+b);
}
return 0;
}
最主要的还是while一句。
4、特殊标记结束
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include
using namespace std;
int main()
{
int a, b;
scanf("%d%d", &a, &b);
while(a!=0 && b!=0)
{
printf("%d\n", a+b);
scanf("%d%d", &a, &b);
}
return 0;
}
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include
using namespace std;
int main()
{
int sum;
int n;
scanf("%d", &n);
while(n!=0)
{
while(n--)
{
int num;
scanf("%d", &num);
sum += num;
}
printf("%d\n", sum);
sum = 0;
scanf("%d", &n);
}
return 0;
}
5、输入字符串
C 语法:
char buf[20];gets(buf);
C++语法:
如果用 string buf;来保存:getline( cin , buf );
如果用 char buf[ 255 ]; 来保存:
cin.getline( buf, 255 );
对字符串的输入分三种情况:
要读入 abc 与 def,可以这样写:
char str1[1000], str2[1000];
scanf("%s%s", str1, str2);
的分界符。对于一个含有空格、制表符及回车的字符串,如果用 scanf("%s",str)来读,将读
到若干个字符串,这个字符串被 scanf 分开了。
可以用另外一个函数 gets。gets 函数用回车作为字符串的分界符,比如,有以下的一个字符
串:
Hello world!
要读入这个字符串,这样写:
char str[1000];
gets(str);
这样,str 的内容就是"Hello world!"了。另外,gets 返回 NULL 表示出错或 end of file。
scanf("%c",&ch)来读,一边读,一边判断分界条件是否满足,如果满足,则把当前读到的东
西存到一个字符串中。
1、每个字符串中不含空格、制表符及回车
这种情况,用 scanf("%s",str)是再好不过的了,比如,测试数据中只有两个字符串:abc def要读入 abc 与 def,可以这样写:
char str1[1000], str2[1000];
scanf("%s%s", str1, str2);
2、字符串中含有空格、制表符,但不含回车
对于这种情况,scanf("%s",str)无能为力,因为 scanf 用空格、制表符及回车作为字符串的分界符。对于一个含有空格、制表符及回车的字符串,如果用 scanf("%s",str)来读,将读
到若干个字符串,这个字符串被 scanf 分开了。
可以用另外一个函数 gets。gets 函数用回车作为字符串的分界符,比如,有以下的一个字符
串:
Hello world!
要读入这个字符串,这样写:
char str[1000];
gets(str);
这样,str 的内容就是"Hello world!"了。另外,gets 返回 NULL 表示出错或 end of file。
3、字符串中含回车
在这种情况下,如果没有题目的说明,程序无法知道哪里是字符串的分界。那么,用scanf("%c",&ch)来读,一边读,一边判断分界条件是否满足,如果满足,则把当前读到的东
西存到一个字符串中。
输入是一整行的字符串的
说明:
scanf(“ %s%s”,str1,str2),在多个字符串之间用一个或多个空格分隔;若使用 gets 函数,应为 gets(str1); gets(str2); 字符串之间用回车符作分隔。
通常情况下,接受短字符用 scanf 函数,接受长字符用 gets 函数,
而 getchar 函数每次只接受一个字符,经常 c=getchar()这样来使用。
getline 是一个函数,它可以接受用户的输入的字符,直到已达指定个数,或者用户
输入了特定的字符。它的函数声明形式(函数原型)如下:
istream& getline(char line[], int size, char endchar = '\n');
不用管它的返回类型,来关心它的三个参数:
char line[]: 就是一个字符数组,用户输入的内容将存入在该数组内。
int size : 最多接受几个字符?用户超过 size 的输入都将不被接受。
char endchar :当用户输入 endchar 指定的字符时,自动结束。默认是回车符。
结合后两个参数, getline 可以方便地实现: 用户最多输入指定个数的字符,如果超过,
则仅指定个数的前面字符有效,如果没有超过,则用户可以通过回车来结束输入。
char name[4];cin.getline(name,4,'\n');
由于 endchar 默认已经是 '\n',所以后面那行也可以写成:
cin.getline(name,4);
char name[4];cin.getline(name,4,'\n');
由于 endchar 默认已经是 '\n',所以后面那行也可以写成:
cin.getline(name,4);
最后需要说明的是, C++的输入输出流用起来比较方便,但速度比 C 要慢得多。在输入
输出量巨大时,用 C++很可能超时,应采用 C 的输入输出。
二、输出
出结果和输出结果在一起, 可能会开个数组,把每组的结果存起来,等输入完了再一起输出。
当遇到不知有多少组测试数据的题,就难以处理了。
其实在 ACM 程序设计竞赛中,输入数据和输出数据是分别在两个不同的文件中进行的,程
序的输入和输出是相互独立的,所以读入一组数据就输出一组结果,跟先读入所有数据再输
出所有的结果,效果是完全一样的。因此,每当处理完一组测试数据,就应当按题目要求进
行相应的输出操作。而不必将所有结果储存起来一起输出。在处理输出时,一般要注意:每
行输出均以回车符结束,包括最后一行。
1. 关于空行(Blank line)
题目说:“After each test case, you should output one blank line”,而有的题目说:“Between
each test case, you should ouput one blank line”。要注意 After 和 Between 的区别,因为如果
多了一或少了空行,将导致 Presentation Error 甚至 Wrong Answer。
After
这种情况最简单,只需要输出结果后,再加一个 printf("\n")或 puts("")就行了,就像这样:
示例:A + B Problem (1003)
Between 和 After 不同的是,最后一组结果后面不应该再加单独的"\n",应该像这样:
由于有时候我们并不知道测试数据有几组(比如测试数据是以 end of file 结束的),用上面
的方法就不行了,于是,可以换一种写法:
这样,从第二组测试数据起,在输出每组测试数据的结果之前就会输出一个空行,和想要的
效果是一样的。
int i;
for (i = 0; i < 10; i++)
{
printf("%d\n", a);
printf("\n");
}
示例:A + B Problem (1003)
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include
using namespace std;
int main()
{
int sum;
int n;
scanf("%d", &n);
while(n!=0)
{
while(n--)
{
int num;
scanf("%d", &num);
sum += num;
}
printf("%d\n", sum);
sum = 0;
scanf("%d", &n);
}
return 0;
}
Between
int i;
for (i = 0; i < 10; i++)
{
printf("%d\n", a);
if (i != 9)
printf("\n");
}
由于有时候我们并不知道测试数据有几组(比如测试数据是以 end of file 结束的),用上面
的方法就不行了,于是,可以换一种写法:
int a;
bool bFirst = true;
while (scanf("%d", &a) == 1)
{
if (!bFirst)
puts("");
else
bFirst = false;
printf("%d\n", a);
}
效果是一样的。
2、关于空格、逗号以及其他分隔符
行了。
3、带格式的字符串输出
abc*****de****f
其中“*”代表空格。
要求是这样的: str1 在前 5 个字符中左对齐, str2 在第 6 到第 10 个字符中右对齐, str3 在第
11 到第 15 个字符中右对齐。
可行的做法是,先初始化一个数组,用' '(空格)填充,再在相应的位置填相应的内容。用
程序来表述:
char str[1000];
char str1[] = "abc", str2[] = "de", str3[] = "f";
memset(str, ' ', 1000 * sizeof(char));
sprintf(str, "%s", str1);
str[strlen(str1)] = ' ';
sprintf(str + 5, "%5s", str2);
str[10] = ' ';
sprintf(str + 10, "%5s", str3);
str[15] = '\0';
puts(str);
关键的部分:
(1)在调用 sprintf 后,要清除不恰当字符串结束符(第 5,7 行);
(2)在恰当的位置添加字符串结束符(第 9 行)。
4、二维数组的输出
int i, j;
for (i = 0; i < nRow; i++)
{
for (j = 0; j < nCol; j++)
{
if (j > 0)
printf(" ");
printf("%d", a[j]);
}
puts("");
}
如果是按列,就要把 2 行和 4行交换。
5、模拟屏幕输出
以采用和带格式的字符串输出相似的方法,先开一个字符数组(在这里,是二维数组),然
后把数组当成屏幕输出,屏幕的(i, j)点就是数组的(i, j)号元素。最后,输出这个二维数组就
行了。
一般来说,可以输出一个二维字符数组的方法和输出一般数组的方法是一样的,用双重循
环来做。不过,可以只用一个循环就可以了,原因是在数组每行的恰当位置(一般是末尾)
加了一个'\0',那么,数组的每一行就成了一个字符串,于是,输出程序就变成了:
int i;
char str[100][100];
...
for (i = 0; i < nRow; i++)
puts(str);
说明
一定要注意每X行(项)输出(Y)个空行(格)