当值彼此相等时,为什么这个if语句没有运行?

时间:2016-02-29 04:26:22

标签: c++

我正在尝试实现这个代码,它在每个字母之间使用Morse代码和3个空格,并获得第一个Morse转换并将其与包含所有莫尔斯代码转换的数组进行比较。在buffer == morsem[j]的位置,缓冲区应该等于.-morsem[j]也应该等于.-;如果j = 0,他们都这样做,但它没有执行if的阻止。知道为什么吗?

#include <iostream>

using namespace std;

int main(){
    char morsem[26][5] = {{".-"},{"-..."},{"-.-."},{"-.."},{"."},{"..-."},{"--."},{"...."},{".."},{".---"},{"-.-"},{".-.."},{"--"},{"-."},{"---"},{".--."},{"--.-"},{".-."},{"..."},{"-"},{"..-"},{"...-"},{".--"},{"-..-"},{"-.--"},{"--.."}};
    char alpha[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char morse[] = ".-   ....";
    int length;
    int first_counter = 0;
    while(morse[first_counter] != '\0'){
        first_counter++;
    }
    char *new_morse = new char [first_counter];
    int counter = 0;

    char *buffer = new char [5];
    for(int x = 0; x < first_counter; x++){
        if(morse[x] != ' '){
            buffer[counter] = morse[x];
            counter++;
        }
        if(morse[x] == ' '&& morse[x+1] == ' ' && morse[x+2] == ' '){
            for(int j=0;j<27;j++){
                if(buffer == morsem[j]){
                    cout << alpha[j] << endl;
                    break;
                }
            }
            for(int i = 0; i < first_counter; i++){
                new_morse[i] = morse[i+x+3];
            }
        }
    }
    delete[] buffer;

    cout << morse << endl;
    cout << new_morse << endl;
}

4 个答案:

答案 0 :(得分:3)

if(buffer == morsem[j]){只是比较指针值而不是字符串。你需要比较&#34;指针指向的是什么&#34;。

由于你使用的是C ++,使用std::string可能比char char缓冲区更容易......

答案 1 :(得分:1)

if(buffer == morsem [j]),你只是比较地址而不是地址的内容。使用字符串类型而不是字符数组。

答案 2 :(得分:0)

你的程序中有未定义的行为,而你的字符串比较错误的事实只会影响这个(更严重的)问题。

char *buffer = new char [5];

这将在内存中的某处创建一个包含5个char元素的动态数组,并为您提供指向这五个元素中第一个元素的指针。与静态morsem数组不同,此处创建的动态数组的元素是未初始化。也就是说,您不能指望它们包含'\0'值。

与字符串文字不同,还会自动添加 no null terminator 。这意味着当您在代码中的某处编写".-"时,编译器会将其视为包含3个元素的数组:'.''-''\0'。通过动态分配,不会发生这样的事情。

现在,在代码的以下部分中:

    if(morse[x] != ' '){
        buffer[counter] = morse[x];
        counter++;
    }

counter可以是5.但尝试访问buffer[5]未定义的行为。由于您创建bufferchar[5],因此唯一有效的索引是0,1,2,3和4.您的程序可以执行任何操作,包括崩溃或随机正常工作。

然后我们进行了错误的字符串比较:

           if(buffer == morsem[j]){

问题是这不是字符串比较。您正在比较两个指针值是否相等。请改用strcmp

现在,一旦您使用strcmp,未初始化的buffer就变得相关了。 strcmp要求两个参数都是以null结尾的字符串。但是,您的代码并不保证buffer[4]'\0'。这又是未定义的行为。您可能没有注意到它,因为morsem[j] 以空值终止,并且您的实现strcmp非常好,只要“\0就停止任何比较}'可以在两个字符串中找到。但这不是一个干净的解决方案。

总而言之,为了解决所有这些问题:

  • 了解 N 元素在数组中可访问的最高索引是 N - 1
  • 了解分配动态char数组会为您留下未初始化的元素,并且不会自动添加'\0'
  • 使用strcmp按字典顺序比较两个char数组。

您还应该使用最高警告级别进行编译,并激活编译器提供的所有运行时检查。例如,使用Visual C ++尝试/MDd选项。它会给你一个很好的崩溃(只是你的系统上的按钮标签可能不是德语:)):

enter image description here

毋庸置疑,在实际代码中,您只需使用std::string并忘记所有这些指针头痛。

答案 3 :(得分:0)

你正在使用很多指针而我没有看到这一点(双关语并非意图)。它经常导致混淆和误解。我个人建议除非必要,否则不要使用它们。它是这里的主要问题,因为它的比较指向了价值观。尝试使用Visual Studio调试器(如果您使用Visual Studio)将其刷新。你对chars的使用是合乎逻辑的,但要注意使用string可以获得相同的结果。