第一次用赛码网,两个小时的笔试居然有一个半小时在查如何正确输入,最要命的是在本地IDE上可以的输入到了网页上就GG了。看来是leetcode刷多了,文件流那块学的也很糟糕。总结一下下次避免跳坑吧。一行的就不说了,用一个多行输入做例子。
6
beijing nanjing
nanjing shanghai
shanghai wuhan
wuhan beijing
xiamen tianjin
tianjin xiamen
题目大意:
小团多次旅游归来,第一行表示他买过的票的总数n;
后面按时间顺序排好这些票,且小团的出游出发地是不固定的,但最后他一定会回到出发的地方,代表他结束了本次旅游。
那么
beijing
nanjing
nanjing shanghai
shanghai wuhan
wuhan beijing
、
xiamen
tianjin
tianjin xiamen
就代表了小团进行了两次旅游
算法非常简单,然鹅我被这个输入浪费了一个小时。
分析:
6是6行,也就是六张票。目标是将每个城市名单独存放,这样考虑使用vector存放string。
cin遇到空格时,认为输入无效
,继而执行后面的语句。
cin遇到换行符与空格和tab时结束读取,例如下面的代码:
string str;
cin >> str;
cout << str;
输入:abcdefg hijk
输出结果将会是:abcdefg
分析一下,cin会根据你定义的数据类型,从输入流中读进去一个该类型数据,直到满足要求
或者遇到空格 换行
等后完成该次输入。所以用
string s;
cin>>s;
来实现以string类型数据为单位的读取操作。
#include <iostream>
#include<vector>
#include<cstring>
#include<string>
#include<sstream>
int main()
{
int n;
cin >> n;
vector<string> store;
string s;
char a;
while (store.size()<2 * n&&cin >> s) {
store.push_back(s);
s.clear();
if (store.size() == 2*n)
break;
}
}
最后的问题解答,全AC,然后做完这个就没时间了哈哈
#include <iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
int main()
{
int n;
cin >> n;
vector<string> store;
string s;
while (store.size()<2 * n&&cin >> s) {
store.push_back(s);
s.clear();
if (store.size() == 2*n)
break;
}
int count = 1;
for (int i = 2; i < 2*n; i = i + 2) {
if (store[i] != store[i - 1])
count++;
}
cout << count << endl;
return 0;
}
输入流的使用分析
这可能是今天笔试的最大收获了吧
假如我们要输入一个char型:
1.直接复制一个count后,无反应,需要按一下回车,只有c被读入a中。
2.手打,输入c后无反应,可再输入多个字符,遇空格无反应,还需要回车。
故复制和手敲输入在这里没啥区别。。
那么遇空格无效到底怎么理解呢?
输入缓冲机制
:
这个缓冲机制规定,只有收到回车键,才会将所有输入的数据一次过提交到输入处理函数(就是 cin 或者 scanf 了)
而这个输入过程,在按下回车键之前,是不受到 cin 和 scanf 控制的…
2.所以说,回车是将输入送到缓冲区,cin再从中读取,其读取过程就和回车无关了。读取的原则就是遇到换行 空格时结束本次读取。
顺便说下换行和空格
的区别。再不同编译器,不同系统中,两者的表示不尽相同。我们在赛码网上复制用例时,每行后面其实跟了个换行符‘\r\n’.
如果你认真看了前文,你肯定也会轻松的明白,不管是你输完一行后手动回车,还是直接复制用例(里面包含了换行),起到的效果时一样的。但还是有必要说一下回车换行的区别。
这一部分主要参考这里
https://www.cnblogs.com/dawn-l/p/5180373.html
C/C++ 中,回车符 '\r' 仅表示回到行首,并没有包含换行的动作,换行是由 '\n' 来完成的,初学者一定要分清这两个符号的意义
。
这里再提一个与 ‘\r’ ‘\n’ 类似的一个转义字符:退格(BS, Backspace)’\b’,顾名思义,这个字符的意义是往前退一格,这里需要特别提醒的是:退格 ‘\b’ 和回车 ‘\r’ 都只是光标的移动,不会删除前面的文本!
现在让我们用一段简单的代码来验证 ‘\r’ ‘\n’ ‘\b’ 的作用效果。
C代码:
1 #include <stdio.h>
2
3 int main(int argc, char const *argv[])
4 {
5 printf("abc\r\ncba\rrr\bz\n");
6 printf("abcd\b\b");
7 getchar();
8
9 return 0;
10 }
C++代码:
#include <iostream>
int main(int argc, char const *argv[])
{
using namespace std;
cout << "abc\r\ncba\rrr\bz\n";
cout << "abcd\b\b";
cin.get();
return 0;
}
首先我们看下输出的第一行 “abc\r\ncba\rrr\bz\n”:
1.在输出 abc 后 \r 使回车符回到当前行即第一行的行首,但不删除字符,所以第一行最终显示 abc,然后 \n 使光标移到下一行,接着输出 cba,\r再次让光标回到行首,这次不换行,直接接着输出 rr,这样达到的效果是行首两个字符 cb 被替换为 rr,接着 \b 使光标向前一位,输出 z,这样第二个 r 就被换成了 z,然后换行,最终第二行显示结果就是 rza。
2.接着为了更直观地证明只有光标移动而不删除字符,我们看看第二行代码。“abcd\b\b”,在两个 \b 过后,光标向前移动到 c 的下面(或者是 c 上的方块光标,亦或是在 c 前的 I 形光标),为了使光标停留以便观察,我们添加了 getchar() 和 cin.get()。
所以程序运行后的结果将是
abc
rza
abcd
同时可以看到光标停留在上述位置,当然,这时如果你再输入字符,就会从光标的位置开始向后将 c 甚至 d 覆盖。
哈哈是不是很有意思,这些基础知识有时不太重视,但却很致命。
介绍另一种输入形式:
用getchar()读取一行,通用形式:(这种方法会把空格也读进去
)
char ch;
while ((ch = getchar()) != '\n')
{
...
}
做一下小实验,a里面存的是’\n’,没有’\r’,这点要注意!!
改进一下,要是要用getchar()来满足今天笔试题的输入需求,将同一行用空格分开的两个地名分别存起来呢?
方法是这样的,注意最后判断a是’\n’来结束本次输入。
char a;
string s;
while (a = getchar()) {
if(a !='\n'&& a !=' ')
s += a;
else {
cout << "刚才输入了:" << s << endl;
s.clear();
if (a == '\n')
break;
}
}
读取多行:(加for循环就行,这是不管空格的简化版本,不太符合我们的需求)
char a;
string s;
for (int i = 0; i < 6; i++) {
while ((a = getchar()) != '\n')
s += a;
cout <<"刚才输入了:"<< s << endl;
s.clear();
}
改进一下 OJBK!!
char a;
string s;
for (int i = 0; i < 3; i++){
while (a = getchar()) {
if (a != '\n'&& a != ' ')
s += a;
else {
cout << "刚才输入了:" << s << endl;
s.clear();
if (a == '\n')
break;
}
}
}
3还有getline(cin,s)这个函数,直接读一行,也是不管空格,感觉在某些场景下挺好用。不再赘述。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)