我在尝试解决 this HackerRank problem 时遇到了这种行为。该站点使用 scanf
将格式良好的数据传递给用户的代码。到目前为止,一切顺利。
有 p
对字符串,每个字符串占单独的一行。对于每一对,我只需要打印 YES
或 NO
一次,具体取决于这两个字符串是否具有公共(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 上尝试此代码,请务必选中针对自定义输入进行测试
复选框,复制并粘贴上面的输入,然后单击运行
按钮。
最佳答案
您的代码具有未定义的行为。您的代码中的问题在于向 s1
和 s2
分配内存。您分配 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/