关于cin的换行符问题

隐无影 2014-08-07 04:42:58
混合输入数字和面向行的字符串会导致问题,如:
Cin>>year;
Cout<<”请输入您的地址”;
Char add[80];
Cin.getline(add,80);
如这样写代码,根本没有输入add(地址的机会)因为cin读取year时,将回车键生成的换行符留在了输入队列,后面的cin.getline()看到换行符后,认为是一个空行,并将一个空字符串赋给add数组

cin>>

该操作符是根据后面变量的类型读取数据。

输入结束条件 :遇到Enter、Space、Tab键。

对结束符的处理 :丢弃缓冲区中使得输入结束的结束符(Enter、Space、Tab)


这两段话有矛盾吧,回车键生成的换行符留在了输入队列 。年一个就说对结束符的处理 :丢弃缓冲区中使得输入结束的结束符。不懂求大侠教
...全文
1954 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Expect_excellent 2014-08-08
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
[quote=引用 4 楼 u011391093 的回复:] 回车键生成的换行符留在了输入队列 。年一个就说对结束符的处理 :丢弃缓冲区中使得输入结束的结束符。回答下这个问题,大侠
cin.clear(); cin.sync();[/quote] 老师我想问下,
int a;
cin>>a>>a;
//像这种为什么不用使用cin.sync();,cin.sync()在什么情况下必须使用,你有总结的博文发给我看看也可以
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
我的总结已经发表在1楼帖子里了。
#include <stdio.h>
char s[]="123 ab 4";
char *p;
int v,n,k;
void main() {
    p=s;
    while (1) {
        k=sscanf(p,"%d%n",&v,&n);
        printf("k,v,n=%d,%d,%d\n",k,v,n);
        if (1==k) {
            p+=n;
        } else if (0==k) {
            printf("skip char[%c]\n",p[0]);
            p++;
        } else {//EOF==k
            break;
        }
    }
    printf("End.\n");
}
//k,v,n=1,123,3
//k,v,n=0,123,3
//skip char[ ]
//k,v,n=0,123,3
//skip char[a]
//k,v,n=0,123,3
//skip char[b]
//k,v,n=1,4,2
//k,v,n=-1,4,2
//End.
mujiok2003 2014-08-08
  • 打赏
  • 举报
回复
我一般这样写:
#include <iostream>
#include <string>
using namespace std;

int main() 
{
 int year;
 cin>>year;
 cout<<"请输入您的地址";
 string add;
 std::getline(cin, add); //get the rest of prev line
 std::getline(cin, add);
 cout << add;
 return 0;
 }
mujiok2003 2014-08-08
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;

int main() 
{
 int year;
 cin>>year;
 cout<<"请输入您的地址";

 //skip all the white spaces
 int ch;
 while((ch =cin.get()) &&  isspace(ch))
 {}
 cin.unget();

 char add[80];
 cin.getline(add,80);
 cout << add;
 return 0;
 }
不要混合使用格式化输入(>>)和非格式输入(read, get, getline..)
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
code generation完爆template
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
grep+sed+gcc完爆g++
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
严重同意楼上。 做个可能不太恰当的比喻: 人想让狗帮忙逮只兔子,可是人说话狗听不懂,于是人发明了一种介乎人言和狗语之间的语言,即口令。 人想让电脑帮忙做计算,可是人话电脑听不懂,于是人发明了一种介乎人言和汇编机器码之间的语言,即C语言。 人对狗的口令得让人容易学、也得让狗容易懂。 C语言同样得让人容易学、也得让电脑容易懂。 相比之下C++、Java就是人学得费劲、电脑也经常闹不懂。 请牢记:源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要,重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。
whoho 2014-08-08
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
乍看起来c++的cin、cout在输入、输出上比c的scanf、printf简单,不用格式控制符! 但是不用格式控制符,输入输出恰好是你期望的格式的时候好说;等到输入输出不是你期望的格式的时候,你就会觉得还是用格式控制符更方便、更靠谱。 摒弃cin、cout! 使用scanf、printf。
赵老师是C的坚定捍卫者,呵呵 其实我也喜欢C啦,有几年在嵌入式系统里天天跟没有free/malloc的C语言打交道 我有一个不同看法需要请您斧正哈, 其实cin cout都有格式控制,无论是分隔符,还是宽度, 或者是数字基数,浮点数格式 只不过很多人都不用罢了 不过说实在的,两相比较,printf和scanf之类,写格式串确实比cout/cin的那些iomanip要显得简短很多
赵4老师 2014-08-08
  • 打赏
  • 举报
回复
引用 8 楼 axf1766567189 的回复:
[quote=引用 7 楼 zhao4zhong1 的回复:] 我的总结已经发表在1楼帖子里了。
#include <stdio.h>
char s[]="123 ab 4";
char *p;
int v,n,k;
void main() {
    p=s;
    while (1) {
        k=sscanf(p,"%d%n",&v,&n);
        printf("k,v,n=%d,%d,%d\n",k,v,n);
        if (1==k) {
            p+=n;
        } else if (0==k) {
            printf("skip char[%c]\n",p[0]);
            p++;
        } else {//EOF==k
            break;
        }
    }
    printf("End.\n");
}
//k,v,n=1,123,3
//k,v,n=0,123,3
//skip char[ ]
//k,v,n=0,123,3
//skip char[a]
//k,v,n=0,123,3
//skip char[b]
//k,v,n=1,4,2
//k,v,n=-1,4,2
//End.
大神, 知道你很牛, 但是你叫别人不实用cin和cout而使用scanf()和printf(), 感觉你有点答非所问呀,[/quote] 试试用istringstream;实现这段代码的功能.
旭日东升1993 2014-08-08
  • 打赏
  • 举报
回复
引用 9 楼 axf1766567189 的回复:
这两段话确实有矛盾, 的一段话说的是正确的, 第二段话说的有点问题. cin >> year; 执行这条语句时, 你从控制台输入数字: 2014 [Enter] 这段输入在计算机系统内被解释为: 2014\n cin 读取了2014之后遇到了\n就停止读取了, 而\n仍然留在了系统缓冲区里面 cin.getline(add,80); 执行这条语句的时候, 系统缓冲区里面仍然有字符'\n', 于是就把 '\n' 读取到了add数组里面去了 楼主可以这样试试:
(cin >> year) >> get();
cout << ”请输入您的地址”;
char add[80];
cin.getline(add,80);
以后编程要养成一个习惯: 每次使用cin 进行输入的时候, 记得在后面加上 get() 函数, 这样就不用考虑这个问题了, 就基本上可以避免这种错误了!
不好意思, 代码搞错了, 应该是

(cin >> year).get();
cout << ”请输入您的地址”;
char add[80];
cin.getline(add,80);
旭日东升1993 2014-08-08
  • 打赏
  • 举报
回复
这两段话确实有矛盾, 的一段话说的是正确的, 第二段话说的有点问题. cin >> year; 执行这条语句时, 你从控制台输入数字: 2014 [Enter] 这段输入在计算机系统内被解释为: 2014\n cin 读取了2014之后遇到了\n就停止读取了, 而\n仍然留在了系统缓冲区里面 cin.getline(add,80); 执行这条语句的时候, 系统缓冲区里面仍然有字符'\n', 于是就把 '\n' 读取到了add数组里面去了 楼主可以这样试试:
(cin >> year) >> get();
cout << ”请输入您的地址”;
char add[80];
cin.getline(add,80);
以后编程要养成一个习惯: 每次使用cin 进行输入的时候, 记得在后面加上 get() 函数, 这样就不用考虑这个问题了, 就基本上可以避免这种错误了!
旭日东升1993 2014-08-08
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
我的总结已经发表在1楼帖子里了。
#include <stdio.h>
char s[]="123 ab 4";
char *p;
int v,n,k;
void main() {
    p=s;
    while (1) {
        k=sscanf(p,"%d%n",&v,&n);
        printf("k,v,n=%d,%d,%d\n",k,v,n);
        if (1==k) {
            p+=n;
        } else if (0==k) {
            printf("skip char[%c]\n",p[0]);
            p++;
        } else {//EOF==k
            break;
        }
    }
    printf("End.\n");
}
//k,v,n=1,123,3
//k,v,n=0,123,3
//skip char[ ]
//k,v,n=0,123,3
//skip char[a]
//k,v,n=0,123,3
//skip char[b]
//k,v,n=1,4,2
//k,v,n=-1,4,2
//End.
大神, 知道你很牛, 但是你叫别人不实用cin和cout而使用scanf()和printf(), 感觉你有点答非所问呀,
赵4老师 2014-08-07
  • 打赏
  • 举报
回复
引用 4 楼 u011391093 的回复:
回车键生成的换行符留在了输入队列 。年一个就说对结束符的处理 :丢弃缓冲区中使得输入结束的结束符。回答下这个问题,大侠
cin.clear(); cin.sync();
隐无影 2014-08-07
  • 打赏
  • 举报
回复
回车键生成的换行符留在了输入队列 。年一个就说对结束符的处理 :丢弃缓冲区中使得输入结束的结束符。回答下这个问题,大侠
赵4老师 2014-08-07
  • 打赏
  • 举报
回复
cin.clear(); cin.sync();
隐无影 2014-08-07
  • 打赏
  • 举报
回复
怎么没人呀,无语
赵4老师 2014-08-07
  • 打赏
  • 举报
回复
乍看起来c++的cin、cout在输入、输出上比c的scanf、printf简单,不用格式控制符! 但是不用格式控制符,输入输出恰好是你期望的格式的时候好说;等到输入输出不是你期望的格式的时候,你就会觉得还是用格式控制符更方便、更靠谱。 摒弃cin、cout! 使用scanf、printf。 参考下面:
//NAME: essaie bla bla
//DIMENSION: 8
//DATA
//1  14  15
//2  11  10
//3  6   4
//4  7   13
//5  9   21
//6  19  3
//7  1   5
//8  8   8
//EOF
//
// 文本文件中可能还含有其他内容,但是需要用到的内容即以上

//比如data.txt:
//NAME: essaie bla bla
//其它内容
//DIMENSION: 8
//其它内容
//DATA
//其它内容
//1  14  15
//其它内容
//2  11  10
//其它内容
//3  6   4
//其它内容
//4  7   13
//其它内容
//5  9   21
//其它内容
//6  19  3
//其它内容
//7  1   5
//其它内容
//8  8   8
//其它内容
//EOF

// 目标是要获取NAME后字串,DIMENSION后数值,以及DATA以下的数值
// 其中NAME就是随便个字句,DIMENSION是城市数量,DATA以下是城市编号,X坐标,Y坐标
// 所有的这些将赋值给一个事先定义好的结构
#include <stdio.h>
#include <string.h>
#define MAXCPL   80   //每行最大字符数
#define MAXCITY  100  //每组数据中DATA最多项数,DIMENSION的最大值
#define MAXNAMEL 32   //NAME最大长度
struct S {
    char NAME[MAXNAMEL+1];
    int  DIMENSION;
    struct D {
        int NO;
        int X;
        int Y;
    } DATA[MAXCITY];
} s;
FILE *f;
int st,n,i;
char ln[MAXCPL];
int main() {
    f=fopen("data.txt","r");
    if (NULL==f) {
        printf("Can not open file data.txt!\n");
        return 1;
    }
    st=0;
    n=0;
    while (1) {
        if (NULL==fgets(ln,MAXCPL,f)) break;
        if (st==0) {
            if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;
        } else if (st==1) {
            if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;
        } else if (st==2) {
            if (0==strcmp(ln,"DATA\n")) st=3;
        } else if (st==3) {
            if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {
                n++;
                if (n>=MAXCITY || n>=s.DIMENSION) break;
            }
        }
    }
    fclose(f);
    printf("s.NAME=[%s]\n",s.NAME);
    printf("s.DIMENSION=%d\n",s.DIMENSION);
    for (i=0;i<n;i++) {
        printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);
    }
    return 0;
}
//s.NAME=[essaie bla bla]
//s.DIMENSION=8
//s.DATA[0].NO,X,Y=1,14,15
//s.DATA[1].NO,X,Y=2,11,10
//s.DATA[2].NO,X,Y=3,6,4
//s.DATA[3].NO,X,Y=4,7,13
//s.DATA[4].NO,X,Y=5,9,21
//s.DATA[5].NO,X,Y=6,19,3
//s.DATA[6].NO,X,Y=7,1,5
//s.DATA[7].NO,X,Y=8,8,8

65,180

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧