C ++:有趣的字符串比较崩溃

时间:2013-01-12 20:18:32

标签: c++ strcmp strncmp

我正在尝试在C ++程序中接受一个简单的命令行参数来触发不同的程序行为 - 当你包含一个“y”(或任何以y开头的字符串 - 我真的不在乎)程序显示一些中间结果。
当我用

运行时
  

ccal pix.txt

一切正常。

当我使用

  

ccal pix.txt yes

它运行正常,显示我的pix并在最后崩溃。

另外,

  

ccal pix.txt no

运行一切正常而不显示像素(就像它应该),并且仍然在最后崩溃。

这是相关的代码 - 我做错了什么?

void dumpFloatMatrix(Mat m){
for(int i = 0; i < m.cols; i++){
    for(int j = 0; j < m.rows; j++){
        char *buff = new char[10];
        sprintf(buff, "%5.1f ", m.at<float>(i,j));
        cout << buff;
        delete buff;
    }
    cout << endl;
}
 }
int main(int argc, char *argv[]){
char* outFile;
bool showPix = false;

// Take in command line args
switch(argc){
case 3:
    if(strncmp(argv[2], "y", 1) == 0)
        showPix = true;
    outFile = argv[1];
    break;
case 2:
    outFile = argv[1];
    break;
default:
    cout << "Usage: ccal INPUT_LIST_FILE" << endl;
    return -1;
}
Mat cameraMatrix(3, 3, CV_32FC1);
dumpFloatMatrix(cameraMatrix);
return 0;
}

奇怪的是,即使我将案例3中的测试切换为这样的事情:

        if(argv[2][0] == 'y')

我仍然有同样的行为。我不能为我的生活找出原因。

2 个答案:

答案 0 :(得分:1)

固定大小的缓冲区对我来说是一个警告信号。

作为故障排除步骤,请更改

sprintf(buff, "%5.1f ", m.at<float>(i,j));

int const used = sprintf(buff, "%5.1f ", m.at<float>(i,j));
assert(used < 10);

除此之外,使用动态分配还是很荒谬的。如果固定大小的缓冲区足够,只需使用本地自动数组变量。当你在它的时候,堆栈空间很便宜,所以通过使缓冲区足够大来阻止溢出。

void dumpFloatMatrix( Mat m )
{
    char buff[400];
    for(int i = 0; i < m.cols; i++){
        for(int j = 0; j < m.rows; j++){
            int const used = sprintf(buff, "%5.1f ", m.at<float>(i,j));
            assert(used * sizeof *buff < sizeof buff);
            cout << buff;
        }
        cout << endl;
    }
}

答案 1 :(得分:1)

抱歉,这是纯粹的疯狂:

for(int j = 0; j < m.rows; j++){
    char *buff = new char[10];
    sprintf(buff, "%5.1f ", m.at<float>(i,j));
    cout << buff;
    delete buff;
}

为10字节数组调用new / delete将花费16-32字节的内存加上您想要的10个字节[可能舍入为16,32或64字节]。并分别调用new和delete。是的,我确信cout << buff会花费更多的周期,但这些都是必要的。

使用:

for(int j = 0; j < m.rows; j++){
    char buff[10];
    sprintf(buff, "%5.1f ", m.at<float>(i,j));
    cout << buff;
}

或使用C ++样式格式:

for(int j = 0; j < m.rows; j++){
    cout << precision(1) << setw(5) << m.at<float>(i,j);
}

如果数组非常大,您可能更喜欢将它们移出循环:

cout.precision(1); 
cout.setw(5);

我更喜欢最后一种方法 - 因为如果您的计算结果为1210121281.9,它将不会溢出[您的布局看起来会有点滑稽]。