为什么我的输出和标准输出一致,却判错了?

P1957 口算练习题

endprophet @ 2021-04-04 00:08:12

在devc++上暂时一切正常,在洛谷的IDE上会在每个等号后面多输出一个换行(原因不明)。 测试数据是1 a 99 999,经测试答案一致。。 下附代码:

#include<bits/stdc++.h>
using namespace std;

int n,i,a,b;
string s="",ans,tmp,k,a1,b1;
stringstream ss;
char now;

char trans(char c){
    if(c=='a') return '+';
    if(c=='b') return '-';
    if(c=='c') return '*';
    return '?';} //不想看那个警告

int suan(int a,int b){
    if(now=='+') return a+b;
    if(now=='-') return a-b;
    if(now=='*') return a*b;
    return -1;}

int main(){
    cin>>n;
    getline(cin,k);
    while(n--){
        getline(cin,s);
        if('a'<=s[0] && s[0]<='z') now=trans(s[0]);//定位运算符
        while (s[i]>'9' || s[i]<'0') i++;//寻找第一个数字,并将后面截取(就是如果有字母就把字母舍弃掉)
        ans=s.substr(i);
        i=0;
        while(ans[i]!=' ') i++;//定位空格
        a1=ans.substr(0,i),b1=ans.substr(i+1);
        ss<<a1; ss>>a; ss.str("");ss.clear();
        ss<<b1; ss>>b; ss.str("");ss.clear();//提取数字
        ans+="=";
        ss<<suan(a,b);//计算,并拼回去
        ss>>tmp; ss.str("");ss.clear();
        ans+=tmp;
        ans[i]=now;
        cout<<ans<<endl<<ans.length();
        if(n!=0) cout<<endl;
        i=0; ans=""; }

    return 0;
}

by QWQasy_mj_wekls @ 2021-04-04 09:11:28

@endprophet 应该是有很多数据的吧.


by metaphysis @ 2021-04-04 09:20:14

@endprophet

洛谷上的测试数据似乎是Windows格式的文本文件,它的换行包含一个回车符,也就是“\r\n”,而Linux格式下的文本文件换行只有一个换行符'\n'。您可能要改变一下输入方法。

为什么我这么说,因为使用以下的代码进行测试,全部运行时错误。

#include<bits/stdc++.h>
using namespace std;

int main(int argc, char * argv[])
{
    cin.unsetf(ios::skipws);   
    char c;
    while (cin >> c) assert(c != '\r');
    return 0;
}

by metaphysis @ 2021-04-04 09:33:39

@endprophet

或者简单点,删去回车符。以下是在您的代码基础上加了一句删除回车符的语句,可以 AC。

#include<bits/stdc++.h>
using namespace std;

int n,i,a,b;
string s="",ans,tmp,k,a1,b1;
stringstream ss;
char now;

char trans(char c){
    if(c=='a') return '+';
    if(c=='b') return '-';
    if(c=='c') return '*';
    return '?';} //不想看那个警告

int suan(int a,int b){
    if(now=='+') return a+b;
    if(now=='-') return a-b;
    if(now=='*') return a*b;
    return -1;}

int main(){
    cin>>n;
    getline(cin,k);
    while(n--){
        getline(cin,s);
        if('a'<=s[0] && s[0]<='z') now=trans(s[0]);//定位运算符
        while (s[i]>'9' || s[i]<'0') i++;//寻找第一个数字,并将后面截取(就是如果有字母就把字母舍弃掉)
        ans=s.substr(i);

        // 删去回车符‘\r’
        ans.pop_back();

        i=0;
        while(ans[i]!=' ') i++;//定位空格
        a1=ans.substr(0,i),b1=ans.substr(i+1);
        ss<<a1; ss>>a; ss.str("");ss.clear();
        ss<<b1; ss>>b; ss.str("");ss.clear();//提取数字
        ans+="=";
        ss<<suan(a,b);//计算,并拼回去
        ss>>tmp; ss.str("");ss.clear();
        ans+=tmp;
        ans[i]=now;
        cout<<ans<<endl<<ans.length();
        if(n!=0) cout<<endl;
        i=0; ans=""; }

    return 0;
}

by metaphysis @ 2021-04-04 09:38:17

应该向管理员反映一下题目的这个问题。


by endprophet @ 2021-04-04 18:41:40

@metaphysis 非常感谢解答,已经解决了,好像是因为 getline 函数在洛谷评测机里的问题


by metaphysis @ 2021-04-04 21:37:19

@endprophet

getline 没有问题,是测试数据的文本文件是 Windows 系统下的文本文件,包含回车符‘\r’所导致的错误。


by endprophet @ 2021-04-04 22:03:10

@metaphysis

getline(cin,k);k.erase(k.size()-1);
    while(n--){
        getline(cin,s);s.erase(s.size()-1);

我把代码改成这样就AC了,原理应该是一样的吧,我那天在翻了好久好久才找到


by metaphysis @ 2021-04-04 23:48:11

@endprophet

是的。


|