c - scanf - 奇怪的行为 : two consecutive calls results in one different string and one correct string

标签 c string scanf

我在尝试解决 this HackerRank problem 时遇到了这种行为。该站点使用 scanf 将格式良好的数据传递给用户的代码。到目前为止,一切顺利。

p 对字符串,每个字符串占单独的一行。对于每一对,我只需要打印 YESNO 一次,具体取决于这两个字符串是否具有公共(public)子字符串。当然,足够简单。但我没有明显的原因导致测试用例失败。

因此,在使用 printf 进行调试后,结果表明,当调用 scanf 两次时,由于某种原因,第一个字符串会变成较短的版本,而第二个字符串会附加到它 - 重叠。第二个字符串通常出现在下一行。

有问题的代码(在 Debug模式下,如果你愿意的话):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int p;
    scanf("%d", &p);

    char *s1 = malloc(sizeof(s1));
    char *s2 = malloc(sizeof(s2));
    int len1, len2;
    char *answers[] = { "NO", "YES"};
    int answers_i;
    for(int i = 0; i < p; ++i) {
        scanf("%s", s1);
        scanf("%s", s2);
        printf("%s\n%s\n", s1, s2);
        len1 = strlen(s1);
        len2 = strlen(s2);
        answers_i = 0;
        for(int j = 0; j < len1 && answers_i == 0; ++j) {
            for(int k = 0; k < len2; ++k) {
                if(s1[j] == s2[k]) {
                    // printf("s1[%d]=%c s2[%d]=%c\n", j, s1[j], k, s2[k]);
                    answers_i = 1;
                    break;
                }
            }
        }
        // printf("%s\n", answers[answers_i]);
    }   

    return 0;
}

输入失败的测试用例之一:

10
dapkqnowwvdrknfvcmanjuroumppajrzklucroxvpfmcsclqa
ivtnjtgiogmwhqybjaxlktqbwsdhqrwovoavetymkpcco
hrtybirxncuiailznohfawjwipdtupnxnisbwcplozwrzt
ngdmqotxkpnuhmpfmajthzdtnztrqyugendiublcwp
rmpwlddwttapjzhdldjmuhmgruufltzszprzdcziigc
bbvvkeqkqekqqennyxqxkxnyxnyqnnybnbvnyqqe
annbjookwtqkoivcgbqckqtvgvktobctktgkkjiac
zsspfhmzpurrrlurdsdlrfldzyldfhudfedrszdpmsudh
yuuuydwovzawzamvydaaadkakukpynwfmpnmuaazokxkmjxawo
rqiqbhgscsetgihrrrgsqrlqgcbcbrettlehbeistbiqbisie
ibvmfltfdvlmentbfdemebbnvllfneeefnaamtblt
gukzzrqruyxsrqhyuggkrjujkwjhqhqsrqgkrkqxpszrzk
nakqzfroqouhgunxqvqbxwtibfodsvoilqrpvhtgzoholxd
bqluorjgkkrvmiptnxegxwlhrstiiafbfoxodzyguhdwi
oyvgelovlyevhhedoeolyhdevcvhgceydcdehgvoc
wsqswjnjpiarszzzxpmptrquwbnbzqiqqtzqnbajnpsjfaxr
hvkmgwawagozzabgmdmdvbbaxadawmbazvxohxzv
sfiltrslqepytjpfffqlrpejiueftrnisnnppnlpuficrjys
nvsovybaljmzenkfgayfoxzcjantbdidxflbkhbixgzk
qdphnbrjmznztnphhutkdbwjzmjwugtxggxchzcidngplj

输出

dapkqnowwvdrknfvcmanjuroumppajrzivtnjtgiogmwhqybjaxlktqbwsdhqrwovoavetymkpcco
ivtnjtgiogmwhqybjaxlktqbwsdhqrwovoavetymkpcco
hrtybirxncuiailznohfawjwipdtupnxngdmqotxkpnuhmpfmajthzdtnztrqyugendiublcwp
ngdmqotxkpnuhmpfmajthzdtnztrqyugendiublcwp
rmpwlddwttapjzhdldjmuhmgruufltzsbbvvkeqkqekqqennyxqxkxnyxnyqnnybnbvnyqqe
bbvvkeqkqekqqennyxqxkxnyxnyqnnybnbvnyqqe
annbjookwtqkoivcgbqckqtvgvktobctzsspfhmzpurrrlurdsdlrfldzyldfhudfedrszdpmsudh
zsspfhmzpurrrlurdsdlrfldzyldfhudfedrszdpmsudh
yuuuydwovzawzamvydaaadkakukpynwfrqiqbhgscsetgihrrrgsqrlqgcbcbrettlehbeistbiqbisie
rqiqbhgscsetgihrrrgsqrlqgcbcbrettlehbeistbiqbisie
ibvmfltfdvlmentbfdemebbnvllfneeegukzzrqruyxsrqhyuggkrjujkwjhqhqsrqgkrkqxpszrzk
gukzzrqruyxsrqhyuggkrjujkwjhqhqsrqgkrkqxpszrzk
nakqzfroqouhgunxqvqbxwtibfodsvoibqluorjgkkrvmiptnxegxwlhrstiiafbfoxodzyguhdwi
bqluorjgkkrvmiptnxegxwlhrstiiafbfoxodzyguhdwi
oyvgelovlyevhhedoeolyhdevcvhgceywsqswjnjpiarszzzxpmptrquwbnbzqiqqtzqnbajnpsjfaxr
wsqswjnjpiarszzzxpmptrquwbnbzqiqqtzqnbajnpsjfaxr
hvkmgwawagozzabgmdmdvbbaxadawmbasfiltrslqepytjpfffqlrpejiueftrnisnnppnlpuficrjys
sfiltrslqepytjpfffqlrpejiueftrnisnnppnlpuficrjys
nvsovybaljmzenkfgayfoxzcjantbdidqdphnbrjmznztnphhutkdbwjzmjwugtxggxchzcidngplj
qdphnbrjmznztnphhutkdbwjzmjwugtxggxchzcidngplj

输出应该等于输入,但显然情况并非如此。第一个字符串的上限为 32 个字符,整个第二个字符串将附加到它后面。但第二个字符串本身没有改变。这两个 scanf 调用之间到底发生了什么?

我使用了 gets (哎呀,已弃用)和 getchar,但问题仍然存在。 fgets 没用,因为我事先不知道字符串的大小。我不知道任何其他标准替代方案。

注意:如果有人想在 HackerRank 上尝试此代码,请务必选中针对自定义输入进行测试复选框,复制并粘贴上面的输入,然后单击运行 按钮。

最佳答案

您的代码具有未定义的行为。您的代码中的问题在于向 s1s2 分配内存。您分配 sizeof(s1) 字节,这是指针的大小。一旦读取的数据多于指针的大小,就会写入超出分配的缓冲区,从而导致未定义的行为。

问题约束需要|a|、|b| < 105,因此分配应如下:

char *s1 = malloc(100000 + 1);
char *s2 = malloc(100000 + 1);

注意为空终止符分配的额外字节。

您需要在函数末尾调用 free(s1)free(s2)

关于c - scanf - 奇怪的行为 : two consecutive calls results in one different string and one correct string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39180133/

相关文章:

c - Arduino:union/struct 属性返回错误值

c - 与**字符**一起使用时作为参数的数组 VS 与**整数**一起使用时

C:从文件中读取某种格式的二维复数数组

java - 如何在java正则表达式中对两个字符进行分组?

regex - 句子中的最后一个单词 : In SQL (regular expressions possible? )

c - 为什么这个程序中的scanf()获取不到输入?

c - Nginx 模块写入 : how to forward request to server?

C 适当使用全局变量

c - 宏中的可变参数

python - 获取所有不以字符开头的字符串的最简单方法是什么?