c ++相同的字符串失败比较检查

时间:2013-01-20 19:31:41

标签: c++ string visual-studio-2012 compare

我被这几天困扰了。我正在我的一个班级上进行单元测试,以确保一切正确。

然而,在比较对象的名称时,我遇到了一个非常奇怪的'错误'。 我调用构造函数时设置名称。根据我传入的注释正确设置名称。但是在这种情况下,BOOST_CHECK失败

为了表明这有多奇怪,这里是调试器中两个字符串的值:

Fdim.name() // "F Diminished"
BOOST_CHECK(Fdim.name() == "F Diminished");  // this fails

以下是两个字符串的规范,取自调试器:

Fdim.name() 
// size - 12, capacity - 15, 
// chars: [70, 32, 68, 105, 109, 105, 110, 105, 115, 104, 101, 100]

"F Diminished" stored inside a variable (to see specs of string)
// size - 12, capacity - 15,
// chars: [70, 32, 68, 105, 109, 105, 110, 105, 115, 104, 101, 100]

正如您所看到的,字符串相同,但==和.compare都失败了。

这是更奇怪的事情:

std::string n = Fdim.name();
std::string r = "F Diminished";
unsigned val = n.compare(r);       // RETURNS 0, everytime
BOOST_CHECK(val == 0);             // fails 
BOOST_CHECK(val == ((unsigned) 0));// fails

我完全傻眼了。当我比较字符串时,val总是返回0(所以它们相等)但是当我比较时,val!= 0?

有谁知道问题可能是什么? 我应该知道的字符串是否有任何属性可能会导致这种比较检查?

修改* * * 字符串存储为std :: string,我不使用char *或cstring。 member _name是std :: string。

这是BOOST OUTPUT:

c:/directory etc(64): error in "ChordIdentification": check val == 0 failed
c:/directory etc(65): error in "ChordIdentification": check n == r failed
c:/directory etc(66): error in "ChordIdentification": check val == ((unsigned) 0) failed
c:/directory etc(67): error in "ChordIdentification": check Fdim.name() == "F Diminished" failed

这是测试用例的代码,只是为了确保人们知道val,n和r是什么:

BOOST_AUTO_TEST_CASE(ChordIdentification)
{
MAKE_NOTE(Db, 'D', FLAT);   // macro that creates a note
MAKE_NOTE(F, 'F', NATURAL);
MAKE_NOTE(Ab, 'A', FLAT);
MAKE_NOTE(Cb, 'C', FLAT);

Chord DbMajor7 = Chord(Cb, Ab, F, Db);
Chord Fdim = Chord(Ab, Cb, F);

CHORD_TEST(DbMajor7, "Db Dominant7", MAJ, THIRD_INVERSION, DOMINANT7); macro of several boost tests, checking members. This test passes completely for this instance of chord. name() check is passed
std::string n = Fdim.name();
std::string r = "F Diminished";
unsigned val = n.compare(r);
//if (val == 0)
BOOST_CHECK(val == 0);
BOOST_CHECK(n == r);
BOOST_CHECK(Fdim.name() == std::string("F Diminished"));    // these strings fail to compare. no idea why, lengths are same, chars same?????
BOOST_CHECK(std::strcmp(Fdim.name(), "F Diminished") == 0);
CHORD_TEST(Fdim, "F Diminished", DIM, FIRST_INVERSION, DIMINISHED); // partially successful, again the string comparison is responsible for this
}

2 个答案:

答案 0 :(得分:3)

我终于发现了为什么会这样。这与调试器无法确定它正在尝试评估的子类实例的事实有关。

正在通过地图识别和弦,具有多态键,具有抽象基类(Composite_Key),子(Composite_Key_2Intervals)和来自该子项的子(Composite_Key_3Intervals)

失败的原因是,对于一个密钥是否确实是3个间隔或2的任何类型的测试总是返回true,因为3个间隔:2个间隔。编译器无法接收到这一点,并且始终返回查找表中找到的错误值。

此外,地图从未在调试器模式下排序,因此插入键的顺序保持不变。但实际上它们正在重新调整,这导致整个评估时调试完全错误。

为了解决这个问题,我现在确保这两个类只从抽象基类继承,因此它们之间没有任何关联。现在所有测试都通过,一切都恢复正常。

此问题的原因仅仅是调试器。它没有适当评估。

答案 1 :(得分:1)

如果我们看一下:

BOOST_CHECK(Fdim.name() == "F Diminished")

然后Fdim.name()是一个C风格的字符串,我希望,因此只是一个指向字符数组的指针 - 该字符数组的地址(很可能)与您文字字符串中的字符串不同BOOST_CHECK()

你可以通过以下方式修复它:

BOOST_CHECK(Fdim.name() == string("F Diminished"))

BOOST_CHECK(strcmp(Fdim.name(), "F Diminished") == 0)