我在尝试解决this HackerRank problem时遇到了这种行为。该网站使用scanf
将格式良好的数据传递给用户的代码。到目前为止,非常好。
有p
对字符串,每个字符串在一个单独的行上。对于每对,我只需要打印YES
或NO
一次,具体取决于这两个字符串是否具有公共子字符串。毫无疑问,直截了当。但是我没有明显的理由没有通过测试用例。
因此,在使用printf
进行调试后,事实证明,当调用scanf
两次时,由于某种原因,第一个字符串变为较短的版本,并附加第二个字符串 - 重叠。第二个字符串通常出现在下一行。
有问题的代码(在调试模式下,如果你愿意的话):
#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
(oops,已弃用)和getchar
,但问题仍然存在。 fgets
没用,因为我事先并不知道字符串的大小。我不知道任何其他标准替代品。
注意:如果有人想在HackerRank上试用此代码,请务必选中Test against custom input
复选框,复制并粘贴上面的输入,然后点击Run
按钮。
答案 0 :(得分:4)
您的代码有未定义的行为。您的代码中的问题是将内存分配到s1
和s2
。您分配sizeof(s1)
个字节,这是指针的大小。一旦读取的数据超过指针大小,就会超过分配的缓冲区,导致未定义的行为。
问题约束要求| a |,| b | &LT; 10 5 ,所以分配如下:
char *s1 = malloc(100000 + 1);
char *s2 = malloc(100000 + 1);
注意为null终止符分配的额外字节。
您需要在功能结束时致电free(s1)
和free(s2)
。