问题:
1.如何从键盘输入字符之后,控制结束输入?
2.回车为什么算入字符?会导致怎样的结果?怎样处理回车?
3.scanf();printf(); /getchar();putchar(); /gets();puts();函数的用法与区别?
相关资料介绍:
在vs2019中:
1.首先是char* 定义指针不能直接赋值,需要使用const char* 类型
2.没有gets函数,scanf_s和scanf函数都不能使用%s进行整段输入
gets函数会造成缓冲区溢出甚至是崩溃,从vs2015就已经将其删除
最新的gets_s()函数的参数需要缓冲内存,所以:整段输入基本失去了意义;
输入一般采用如下方式:
const int ControlNum = 50; //定义最大上限
printf("\nControl+Z结束\n\n"); //采用EOF结束
for (int Num = 0;; Num++)
{
Middle = getchar(); //中间变量先接收,判断是否结束
if (Middle == EOF)
{
Middle = '\0'; //如果结束就将最后变为'\0'一以便使用%s格式整段输出
Word[Num] = Middle;
break;
}
if (Num <= ControlNum - 1)
{
Word[Num] = Middle;
} //在未超出数组接收最大上限时录入,否则不予录入
}
3.在进行字符输入的时候计算机会为输入的字符开辟内存形成消息队列。
如果使用getchar()函数一次输入很多字符(输入很多字符才按回车),那么这些字符会存储在消息队列中,下次getchar()的时候就会自动使用消息队列中第一个消息而直接跳过输入。
解决办法:
包含头文件conio.h,调用其中的getch()函数<_getch()函数>;此函数能够直接输入不需要回车,也就自然避免了在一行输入很多内容,堵满了消息队列的情况。
conio是Console Input/Output(控制台输入输出)的简写,其中定义了通过控制台进行数据输入和数据输出的函数。
调用getch()函数;在VS2019中getch()函数被视为不安全函数,需要调用_getch()函数;
问题解决:
1.问题1:如上图所示,采用一个中间量来读取数据,反复判断是否达到退出输入条件?
若达到:退出,最后一个成员录入'\0'。
若未达到:把中间值赋给数组,并接收新的数据。
2.问题2:回车在ASCII表中是'\r',但是实际录入的是'\n'即换行。所以在判定回车的时候需要使用'\n'判定。'\n'也是一个字符,在调用getchar()的时候会被接收。
导致的结果:回车生成的'\n'也会被录入消息队列中,下次再调用getchar()函数的时候,直接读取消息队列第一个,跳过了输入。
解决办法:
方法1:如果使用getchar()函数,首先定义一个char EatEnter吃回车。再在getchar()函数后加上一个EatEnter = getchar();吃掉回车产生的'\n',阻止其进入消息队列。
方法2:采用_getch()函数,直接跳过回车,让消息队列接受就立刻处理,自然不会有游离的'\n'留在消息队列中,导致下次输入时直接跳过导致出错。
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include<conio.h> //此条为调用_getch()函数
const int ControlNum = 50; //定义最大存储量
char Word[ControlNum]; //存储字符数组
char Middle;
char Choose; //选择结束输入模式
ChooseBegin:Choose = _getch();//调用免去回车的_getch()函数
if (Choose == 'A')
{
printf("\n回车结束模式\n\n");
for (int Num = 0;; Num++)
{
Middle = getchar();
if (Middle == '\n')
{
Middle = '\0';
Word[Num] = Middle;
break;
}
if (Num <= ControlNum - 1)
{
Word[Num] = Middle;
}
}
}
else
{
printf("\n错误,请从新输入\n");
putchar(Choose); printf("\n");
goto ChooseBegin; //goto语句,从新输入
}