Сравнить строки - PullRequest
       17

Сравнить строки

1 голос
/ 02 марта 2011

Спасибо! Работает отлично сейчас. Ява сделала меня глупым: (

У меня возникают некоторые трудности при сравнении строк в C. Я получаю правильный вывод, когда не использую свою функцию isMorse, но когда я использую ее, вывод становится неточным и отображает случайные символы. Насколько я могу судить, переменная "morse" фактически изменяется при вызове strcmp. Я думаю, что это связано с тем, что «Морзе» не является константой, но я не уверен, как это исправить.

Спасибо !!

char *EnglishToMorse(char english)
{
   static char *morse;

   int i;
   for (i = 0; i < LOOKUP_SIZE; i++)
   {
      if (lookup[i].character == english)
      {
         morse = lookup[i].morse;
         return morse;
      }
   }

   morse = &english;  // Problem was here!!!
   return morse;
}

Ответы [ 5 ]

3 голосов
/ 02 марта 2011

Я немного догадываюсь.Функция EnglishToMorse() может возвращать указатель на память из стека.Если это так, запуск другой функции после EnglishToMorse() изменит эту память.Это может произойти из-за ошибки в EnglishToMorse() - объявление локального массива char и возвращение указателя на него.

Без просмотра кода для EnglishToMorse(), это всего лишь удар втемно.Вы можете предоставить нам больше кода, чтобы посмотреть и выиграть.

1 голос
/ 02 марта 2011

У вас есть статическая переменная в EnglishToMorse, но она неправильная. Морзе не нужно быть статичным - вы просто возвращаете его. Но вам нужно, чтобы английский был статичным, а не в стеке, поскольку вы возвращаете его адрес. Кроме того, это должна быть строка, оканчивающаяся NUL. Сделать что-то вроде

char *EnglishToMorse(char english)
{
   static char save_english[2]; /* initialized to 0's */ 

   int i;
   for (i = 0; i < LOOKUP_SIZE; i++)
      if (lookup[i].character == english)
         return lookup[i].morse;

   save_english[0] = english;
   return save_english;
}

Обратите внимание, однако, что вызывающая программа EnglishToMorse должна использовать результат или сохранить его перед повторным вызовом EnglishToMorse, поскольку второй вызов может перезаписать static_english.

0 голосов
/ 02 марта 2011

Причина, по которой ваша переменная morse меняется, заключается в том, что она указывает на область в стеке.Причина, по которой он указывает на область в стеке, заключается в том, что вы присвоили ему адрес вашего параметра english, который был помещен в стек при вызове вашей функции, а затем вытолкнут из стека после завершения функции.

Теперь ваша переменная Морзе будет указывать на то, какая память занимает одно и то же место в стеке, которое будет постоянно меняться на протяжении всей жизни вашей программы.

На мой взгляд, лучший способ решить эту проблему - это вернутьNULL-указатель из EnglishToMorse, если символ не является AZ ..., тогда проверьте наличие NULL-указателя в вашей функции isMorse.В конце концов, хорошей практикой является проверка указателей NULL в коде.

char* EnglishToMorse(char english)
{
    int i;

    english = toupper(english);
    for (i = 0; i < LOOKUP_SIZE; i++)
    {
        if (lookup[i].character == english)
            return lookup[i].morse;
    }

    return NULL;
}

int isMorse(char* morse)
{
    int i;

    /* Check for NULL, so strcmp doesn't fail. */
    if (morse == NULL) return 0;

    for (i = 0; i < LOOKUP_SIZE; i++)
    {
        if(strcmp(morse, lookup[i].morse) == 0) 
            return 1;
    }

    return 0;
}
0 голосов
/ 02 марта 2011

char *EnglishToMorse(char english)
и
morse = &english;
являются проблемой.

Вы никогда не должны возвращать указатель на локальную переменную или параметр функции.

0 голосов
/ 02 марта 2011

Похоже, проблема, вероятно, в этой функции:

char *EnglishToMorse(char english) {
    static char *morse;
    // ...
    morse = &english;
    return morse;
}

Вы возвращаете адрес параметра (english), который передан в функцию.Этот параметр перестает существовать после возврата функции (и до того, как вызывающая сторона получит шанс увидеть значение).Похоже, что вы пытались исправить это, объявив переменную morse статической, но это только делает переменную morse самой статической, а не то, на что она указывает.

Кроме того, строки в C должны заканчиваться символом NUL.Возвращая указатель на один символ (как в english), нет никакой гарантии, что следующий байт в памяти является или не является символом NUL.Таким образом, вызывающая сторона, ожидающая увидеть строку с NUL-окончанием, может получить больше, чем рассчитывала.

...