PTA无法使用gets函数?解决读取字符串问题

本文介绍了在编程中处理PTA题目时,如何解决gets函数在C/C++中的使用问题,包括scanf的特殊用法、getline替代、去除空格和换行符,以及利用while和for循环进行字符读取的方法。
摘要由CSDN通过智能技术生成

在做PTA上的题目时,常常会要求读取字符串,但是会遇到gets无法使用或者用scanf("%s")却没法读取空格,以下有四种办法解决输入字符串时遇到的问题。

一、gets(适用于c)

其实gets函数是包含在stdio.h这个函数库里,但无法使用或者读取空白有以下原因:

1、编译器原因,在c++编译器里会报错。

2、先读常数后读字符串读到空白,PTA测试点里每一行结尾都换行符:\n(最后一行不一定有),当gets读到时会结束读取,所以会什么都没读到就结束了读取。

解决办法:

1、换编译器,用c的编译环境。

2、用getchar读掉\n或者在用scanf读取常数时加一个空格,挤掉\n的位置。

例如要读取以下数据(PTA中:L1-039 古风排版)

4
This is a test case
int n;
char a[1000]

//错误输入,只读到一部分字符,第一个空格以后读不到
scanf("%d",&n);
scanf("%s",&n);

//错误输入,常数后面带有'\n',gets读到'\n'后就结束了,导致gets什么都没读到
scanf("%d",&n);
gets(a);

//正确输入,把'\n'读掉后gets正常读取
scanf("%d",&n);
getchar();
gets(a);

//正确输入,用空格把'\n'的位置占掉,gets正常读取
scanf("%d ",&n);
gets(a);

二、getline(适用于c++)

gets在c++的编译环境里无法使用,但是可以用getline代替gets,要注意的是,getline也是读到‘\n’就停止,所以还是要读掉缓冲区的'\n'。

int n;
string a;

//错误读取,gets无法在c++中使用
cin>>n;
gets(a);

//错误读取,'\n'导致getline读空
cin>>n;
getline(cin,a);

//正确读取,用cin.ignore()读掉回车
cin>>n;
cin.ignore();
getline(cin,a);

//正确读取,用空格占掉回车
scanf("%d ",&n);
getline(cin,a);

三、scanf的特殊用法(c和c++通用)

在scanf里有一种特殊的读取方式是区间读取,格式:scanf("%[ ]",n);。

%[ ]表示输入内容的范围,也就是区间,例如%[0-9]就是只输入'0'到'9'之间的字符,%[a-z]就是'a'到'z',如此类推还有%[A-Z]等等

那要读取除除了'\n'之外的字符要怎么做?在数学有关区间的知识中'^'表示非,所以我们可以在[ ]里加'^\n'表示除了回车以外的集合,这样就可以读取了,要注意的是如果读到了回车scanf会退出读取或读取到奇特的字符,所以依然要想办法把常数后带的回车去掉

int n;
char a[1000]

//错误输入,读到奇怪字符或空
scanf("%d",&n);
scanf("%[^\n]",&n);

//错误输入,读到奇怪字符或空
cin>>n;
scanf("%[^\n]",&n);

//正确读取
scanf("%d ",&n);
scanf("%[^\n]",&n);

//正确读取
scanf("%d",&n);
getchar();
scanf("%[^\n]",&n);

//正确读取
cin>>n;
cin.ignore();
scanf("%[^\n]",&n);

除此之外,scanf还有一个特殊字符'*',%*[\n]表示从第一个字符开始匹配,匹配条件:是字符‘\n’。如果满足条件,则忽略掉该字符,继续匹配,不满足条件,则停止匹配。

int n;
char a[1000]

//正确读取,从回车开始匹配
scanf("%d",&n);
scanf("%*[\n]%[^\n]",&n);

利用scanf的特殊输入,我们可以做到读取快速和准确。 

四、while或者for循环判断

一种少见的用法,利用循环一个个读取字符,判断读取的是否是想要的字符。

char a[1000],c;
int flag=0,i=0;

//读取结果与上面三种方法正确读取一样,但是效率低,常用于统计字符种类或操作字符串
while(1)
{
    c=getchar();
    if(c=='\n')
    {
        flag++;
        if(flag>=2)break;
    }
    else
    {
        a[i]=c;
        i++;
    }
}

for(i=0;flag<2;i++)
{
    c=getchar();
    if(c=='\n')flag++;
    else a[i]=c;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值