输入输出专题
控制小数点后精度位数及补齐整数位数
#include <cstdio>
#include <cstdlib>
int main(){
int n=9;
double pi=3.1415926;
printf("%02d\n",n); //保存两位然后补齐,输出09
printf("0.3f\n",pi); //小数保留三位,输出3.142
return 0;
}
scanf输入规则
//输入字符
char c;
scanf("%c",&c);
//输入字符串
char a[26],b[10];
scanf("%s%s",a,&b);
//不同整型输出
short a = 10;
int b = 100;
long c = 9437;
printf("a=%hd, b=%d, c=%ld\n", a, b, c);
# include <stdio.h>
int main(void)
{
char str1[10], str2[10], str3[10];
printf("请输入字符串:");
scanf("%s%s%s", str1, str2, str3);
printf("输出结果:%s %s %s\n", str1, str2, str3); //%s间要加空格
return 0;
}
//需要注意的是,前面讲“清空缓冲区”的时候讲过,用 scanf 输入时,不管输入什么,最后“敲”的回车都会被留在缓冲区,这里也不例外。输入字符串时最后“敲”的回车也会被留在缓冲区,如果紧接着要给一个字符变量赋值的话,那么还没等你输入系统就自动退出来了。因为系统自动将回车产生的字符 '\n' 赋给该字符变量了,所以此时对字符变量赋值前要首先清空缓冲区。
其他输入规则,getchar(),cin,get(),gets()如何终止循环输入跳出
string str;
while(cin>>str){
char ch=getchar();
if(ch=='\n') break;
}
//另一种强悍输入,每一次可以读两个东西
while((cin>>word).get(c)&&flag){
if(c=='\n'){
flag==false;
}
for (int i = 0; i < word.size(); i++)
{
count[tolower(word[i])]++; //将字符全部转换为小写,并以ascii值为下标,数组值为出现次数计数
}
words.push_back(word);
if (!flag) //判断回车
{
break;
}
}
第一:要注意不同的函数是否接受空格符、是否舍弃最后的回车符的问题!
读取字符时:
scanf()以Space、Enter、Tab结束一次输入,不会舍弃最后的回车符(即回车符会残留在缓冲区中);
getchar()以Enter结束输入,也不会舍弃最后的回车符;
回车本身也是一个字符,getchar得到的是键盘流字符,须要清除一下键盘缓冲区:如用fflush(stdin); rewind(stdin);等
读取字符串时:
scanf()以Space、Enter、Tab结束一次输入
gets()以Enter结束输入(空格不结束),接受空格,会舍弃最后的回车符!
第二:为了避免出现上述问题,必须要清空缓冲区的残留数据,可以用以下的方法解决:
方法1:C语言里提供了函数清空缓冲区,只要在读数据之前先清空缓冲区就没问题了!
这个函数是fflush(stdin)。
方法2:自己取出缓冲区里的残留数据。
(说实话这个语句我也没看懂,呵呵!为什么格式控制是这样的!希望高手指点一下!)
scanf("%[^\n]",string);
//getchar()的正确使用方式
int main(void)
{
int ch;
int line_no = 0;
int flag = 1;
while((ch = getchar()) != EOF)
{
if (flag)
{
printf("%d--", line_no);
flag = 0;
}
putchar(ch);
if(ch == '\n')
{
line_no++;
flag = 1;
}
}
}
getchar:int getchar(void);从标准输入流(stdin,通常是键盘)中读取一个字符。
函数声明在头文件<stdio.h>中。 getc:
int getc(FILE *stream);
从文件流中读取一个字符。
函数声明在头文件<stdio.h>中。 fgetc:
与 getc 完全相同,从文件中读取一个字符。
scanf("%d", &n) 是从标准输入读入一个整数赋值给n,并且返回值是读入的值。
while( scanf(..) != EOF ) 就是一直从读取数据,直到读到一个EOF标记为止
EOF 是 end of line的意思,也就是行结束标识
getline(cin,str)输入一行//gets也是一行,但是需要char arr[100]型
string str;
while(getline(cin,str)){
if(islower(str[0])) str[0]=toupper(str[0]);
for(int i=1;i<str.size();i++){
if((str[i]==' '&&isalpha(str[i+1]))||(str[i]=='\t'&&isalpha(str[i+1]))||(str[i]=='\r'&&isalpha(str[i+1]))||(str[i]=='\n'&&isalpha(str[i+1]))){
if(islower(str[i+1])) str[i+1]=toupper(str[i+1]);
}
}
cout<<str<<endl;
}
cin.get()该函数有三种格式:无参,一参数,二参数即cin.get(),cin.get(char ch), cin.get(array_name, Arsize) 读取字符的情况:输入结束条件:Enter键对结束符处理:不丢弃缓冲区中的Entercin.get() 与 cin.get(char ch)用于读取字符,他们的使用是相似的,即:ch=cin.get() 与 cin.get(ch)是等价的。
sstream输入流
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
string str;
while(getline(cin,str)){
string word1;
string word2;
//隔行的还是选择行读好了,使用cin有风险,不用置零,清一下vec即可
getline(cin,word1);
getline(cin,word2);
//输入流输入范例
string buf;
stringstream ss(str);
vector<string> vec;
while(ss>>buf) vec.push_back(buf);
for(auto it=vec.begin();it!=vec.end();it++){
if(*it==word1) *it=word2;
cout<<*it<<" ";
}
cout<<endl;
vec.clear();
}
return 0;
}
//int型转string型变得这么简单
stringstream sstream;
string strResult;
int nValue = 1000;
// 将int类型的值放入输入流中
sstream << nValue;
// 从sstream中抽取前面插入的int类型的值,赋给string类型
sstream >> strResult;
cout << "[cout]strResult is: " << strResult << endl;
printf("[printf]strResult is: %s\n", strResult.c_str());
//string型转int型
int str_to_int(const string &string_temp){
int temp;
stringstream stream(string_temp);
stream>>temp;
return temp;
}
sstream输入排序实例istringstream
/*
考察字符串的划分和排序
我用的是istringstream 对读入的字符串进行划分,但是时间会比sscanf慢
毕竟io还是c快的多
*/
#include <bits/stdc++.h>
using namespace std;
struct Log{
string s; // 保存原本的数据
string name; // 名字
double time; // 记录时间
}logs[10000];
bool cmp(Log a,Log b){ // 排序函数
if(a.time == b.time) return a.name<b.name;
else return a.time<b.time;
}
int main(){
int i = 0;
while(getline(cin,logs[i].s)){ // 读入一行
istringstream is(logs[i].s); // 绑定s,对读入的数据进行划分
string str1,str2,str3;
//hs_10000_p 2007-01-17 19:22:53,315 253.035(s)
is>>str1>>str2>>str3>>logs[i].time;
logs[i].name = str2+str3;
i++;
}
sort(logs,logs+i,cmp); // 排序
for(int j=0;j<i;j++){
cout<<logs[j].s<<endl;
}
}
sscanf输入实例
#include <cstdio>
#include <algorithm>
using namespace std;
struct Message {
char raw[101];
char task[21];
int year, month, day;
int hour, minute, second, msecond;
int timeSecond, timeMsecond;
bool operator < (const Message& b) const {
if(timeSecond != b.timeSecond) return timeSecond < b.timeSecond;
if(timeMsecond != b.timeMsecond) return timeMsecond < b.timeMsecond;
if(year != b.year) return year < b.year;
if(month != b.month) return month < b.month;
if(day != b.day) return day < b.day;
if(hour != b.hour) return hour < b.hour;
if(minute != b.minute) return minute < b.minute;
if(second != b.second) return second < b.second;
return msecond < b.msecond;
}
} message[10000];
int main() {
int cnt = 0;
while(gets(message[cnt].raw)) {
sscanf(message[cnt].raw, "%s %d-%d-%d %d:%d:%d,%d %d.%d",
message[cnt].task, &message[cnt].year, &message[cnt].month,
&message[cnt].day, &message[cnt].hour, &message[cnt].minute,
&message[cnt].second, &message[cnt].msecond, &message[cnt].timeSecond, &message[cnt].timeMsecond);
cnt++;
}
sort(message, message+cnt);
for(int i = 0; i < cnt; i++) {
printf("%s\n", message[i].raw);
}
return 0;
}