criyle / go-judge

Sandbox Server in REST / gRPC API. Based on Linux container technologies.
MIT License
429 stars 66 forks source link

输入方式不同时,得出的结果不一致 #114

Closed Mai-c1 closed 3 months ago

Mai-c1 commented 3 months ago

我的c++代码中使用了getline读取一整行字符串,即使使用getchar消除换行符,输出结果也和预期不一致 我编译了一个cpp文件

#include <bits/stdc++.h>
#define int long long
using namespace std;
int t;

void solve(){
    string s;
    getline(cin,s);
    map<char,int>mp;
    mp['a']=0;mp['e']=0;mp['i']=0;mp['o']=0;mp['u']=0;
    for(char x:s){
        if(mp.count(x)){
            mp[x]++;
        }
    }
    for(auto p:mp){
        cout<<p.first<<":"<<p.second<<endl;
    }
    if(t!=0)cout<<endl;
    return;
}

signed main(){
    cin>>t;getchar();while(t--)solve();
    return 0;
}

发送的具体命令为

{
    "cmd": [{
        "args": ["/usr/bin/g++", "main.cc", "-o", "main"],
        "env": ["PATH=/usr/bin:/bin"],
        "files": [
            {"content": ""},
            {"max": 536870912, "name": "stdout"},
            {"max": 10240, "name": "stderr"}
        ],
        "cpuLimit": 20000000000,
        "memoryLimit": 34359738368,
        "procLimit": 50,
        "copyIn": {
            "main.cc": {
            "content": "#include <bits/stdc++.h>\n#define int long long\nusing namespace std;\nint t;\n\nvoid solve(){\n\tstring s;\n\tgetchar();\n\tgetline(cin,s);\n\tmap<char,int>mp;\n\tmp['a']=0;mp['e']=0;mp['i']=0;mp['o']=0;mp['u']=0;\n\tfor(char x:s){\n\t\tif(mp.count(x)){\n\t\t\tmp[x]++;\n\t\t}\n\t}\n\tfor(auto p:mp){\n\t\tcout<<p.first<<\":\"<<p.second<<endl;\n\t}\n\tif(t!=0)cout<<endl;\n\treturn;\n}\n\nsigned main(){\n\tcin>>t;while(t--)solve();\n\treturn 0;\n}"
            }
        },
        "copyOut": ["stdout", "stderr"],
        "copyOutCached": ["main"]
        }
    ]
}

1、手动指定输入

{
    "cmd": [{
        "args": ["a"],
        "env": ["PATH=/usr/bin:/bin"],
        "files": [{
            "content": "2\nbmofyemojcucscszkmymcqdjejdhoehcykaqdccbdtpgchonquxoh\nrnrjutgalqyplktnoyqkqgxyqoiicr lwgggdtgatj idlfdghpehbvasqj"
        }, {
            "name": "stdout",
            "max": 10240
        }, {
            "name": "stderr",
            "max": 10240
        }],
        "cpuLimit": 10000000000,
        "memoryLimit": 104857600,
        "procLimit": 50,
        "copyIn": {
            "a": {
                "fileId": "6BSMCTSZ" // 这个缓存文件的 ID 来自上一个请求返回的 fileIds
            }
        }
    }]
}

结果为

[
    {
        "status": "Accepted",
        "exitStatus": 0,
        "time": 2104275,
        "memory": 262144,
        "runTime": 2563840,
        "files": {
            "stderr": "",
            "stdout": "a:1\ne:3\ni:0\no:5\nu:2\n\na:3\ne:1\ni:3\no:2\nu:1\n"
        }
    }
]

2、指定输入文件路径

{
    "cmd": [{
        "args": ["main"],
        "env": ["PATH=/usr/bin:/bin"],
        "files": [
            {"src": "/judge/case/HDOJ-2027/1723180567999/in/0.in"},
            {"max": 536870912, "name": "stdout"},
            {"max": 10240, "name": "stderr"}
        ],
        "cpuLimit": 1500000000,
        "memoryLimit": 34695282688,
        "procLimit": 50,
        "copyIn": {
            "main": {"fileId": "6BSMCTSZ"}
        },
        "copyOut": null,
        "copyOutCached": null
    }]
}

输出结果为

[
    {
        "status": "Accepted",
        "exitStatus": 0,
        "time": 2326121,
        "memory": 262144,
        "runTime": 2849898,
        "files": {
            "stderr": "",
            "stdout": "a:0\ne:0\ni:0\no:0\nu:0\n\na:1\ne:3\ni:0\no:5\nu:2\n"
        }
    }
]

文件内容为

2
bmofyemojcucscszkmymcqdjejdhoehcykaqdccbdtpgchonquxoh
rnrjutgalqyplktnoyqkqgxyqoiicr lwgggdtgatj idlfdghpehbvasqj

两个结果的stdout不一致,手动指定输入结果和我跑出来的是一样的 其他语言没什么问题,唯独C++ 在使用getline函数时,会发生这个问题

Mai-c1 commented 3 months ago

不好意思复制有误,编译命令为

{
    "cmd": [{
        "args": ["/usr/bin/g++", "main.cc", "-o", "main"],
        "env": ["PATH=/usr/bin:/bin"],
        "files": [
            {"content": ""},
            {"max": 536870912, "name": "stdout"},
            {"max": 10240, "name": "stderr"}
        ],
        "cpuLimit": 20000000000,
        "memoryLimit": 34359738368,
        "procLimit": 50,
        "copyIn": {
            "main.cc": {
            "content": "#include <bits/stdc++.h>\n#define int long long\nusing namespace std;\nint t;\n\nvoid solve(){\n\tstring s;\n\tgetline(cin,s);\n\tmap<char,int>mp;\n\tmp['a']=0;mp['e']=0;mp['i']=0;mp['o']=0;mp['u']=0;\n\tfor(char x:s){\n\t\tif(mp.count(x)){\n\t\t\tmp[x]++;\n\t\t}\n\t}\n\tfor(auto p:mp){\n\t\tcout<<p.first<<\":\"<<p.second<<endl;\n\t}\n\tif(t!=0)cout<<endl;\n\treturn;\n}\n\nsigned main(){\n\tcin>>t;\ngetchar();while(t--)solve();\n\treturn 0;\n}"
            }
        },
        "copyOut": ["stdout", "stderr"],
        "copyOutCached": ["main"]
        }
    ]
}

不过结果仍然不符合预期

criyle commented 3 months ago

请检查文件换行符,windows 下造的数据是 \r\n 换行,和 linux 下不一致,会使 getline 出问题。

Mai-c1 commented 3 months ago

请检查文件换行符,windows 下造的数据是 \r\n 换行,和 linux 下不一致,会使 getline 出问题。

确实是换行符造成的原因,问题已经解决了,谢谢你