Ломаю голову над простой функцией
- Войдите на сайт для отправки комментариев
Вс, 07/01/2018 - 04:13
Здраствуйте, я понимаю что есть куча готовых функций сравнений 2х строк, но попробовав написать свою функцию в завел себя в тупик.
unsigned char String_Compare(unsigned char* Str1, unsigned char* Str2)
{
unsigned char i;
unsigned char flag = 1;
unsigned char size1 = 0;
unsigned char size2 = 0;
size1 = sizeof Str1 / sizeof Str1[0];
size2 = sizeof Str2 / sizeof Str2[0];
if(size1 == size2)
{
for(i = 0; i < size1; i++)
{
if(Str1[i] != Str2[i])
{
flag = 0;
}
}
}
else
{
flag = 0;
}
return flag;
}
unsigned char s1[] = {"abcde"};
unsigned char s2[] = {"abcdd"};
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print(String_Compare(s1, s2));
delay(1000);
}
я непойму почему функция возвращает единицу при заведомо ложных строках :)
Видимо, потому, что первые буквы одинаковые. Посмотрите внимательно - у вас совпадение символа хотя бы на одной позиции меняет flag на ноль с концами. Кстати, если длина строк будет разная - то тоже гарантированно вернет ноль.
Видимо, потому, что первые буквы одинаковые. Посмотрите внимательно - у вас совпадение символа хотя бы на одной позиции меняет flag на ноль с концами. Кстати, если длина строк будет разная - то тоже гарантированно вернет ноль.
В строке 13 стоит != а значит любое НЕСОВПАДЕНИЕ в строке должно вернуть 0, но не возвращает
Ой! Извиняюсь за невнимательность, наискосок код читал... Сейчас глянул повнимательнее.
Могу ошибаться, но видимо, ошибка в использовании sizeof - вы используете его для определения длины строки, а на самом деле Str1 у вас не строка, а указатель на массив. Хотя сам не сишник, возможно, меня кто-нибудь поправит :) .
Упс, глянул вот тут: https://learnc.info/c/arrays.html.
По ходу, для вашей задачи нужно вместо массива символов объект String пользовать.
Ой! Извиняюсь за невнимательность, наискосок код читал... Сейчас глянул повнимательнее.
Могу ошибаться, но видимо, ошибка в использовании sizeof - вы используете его для определения длины строки, а на самом деле Str1 у вас не строка, а указатель на массив. Хотя сам не сишник, возможно, меня кто-нибудь поправит :) .
Убрал if и for конструкции и написал return size1, действительно, вернул только 2 вместо 6
Так не?...
// ---------------------------------------------------------------------------- // Функция _strcmp() сравнивает в лексикографическом порядке две строки // и возвращает целое значение, зависящее следующим образом от результата // сравнения: // Нуль .......... str1 == str2 // Больше нуля ... str1 != str2 // !!! НЕ СООТВЕТСТВУЕТ БИБЛИОТЕЧНОЙ (C89) ФУНУЦИИ strcmp !!! // bool _strcmp(const char* str1, const char* str2) { uint8_t i = 0; for (i = 0; * (str1 + i) == *(str2 + i) != 0; i++) if (*(str1 + i) == 0) return 0; return *(str1 + i) - *(str2 + i); }Пробуйте :) .
А вообще, такая форма записи мне кажется совершенно нечитаемой - я бы лучше вместо for в таких конструкциях пользовал бы while. Но это по вкусу. И еще - такой метод предполагает, что строка обязательно заканчивается нулевым символом. Про это вот тут почитать можно: http://arduino.ru/Reference/String.
Так не?...
// ---------------------------------------------------------------------------- // Функция _strcmp() сравнивает в лексикографическом порядке две строки // и возвращает целое значение, зависящее следующим образом от результата // сравнения: // Нуль .......... str1 == str2 // Больше нуля ... str1 != str2 // !!! НЕ СООТВЕТСТВУЕТ БИБЛИОТЕЧНОЙ (C89) ФУНУЦИИ strcmp !!! // bool _strcmp(const char* str1, const char* str2) { uint8_t i = 0; for (i = 0; * (str1 + i) == *(str2 + i) != 0; i++) if (*(str1 + i) == 0) return 0; return *(str1 + i) - *(str2 + i); }Так да, просто хотел свое написать)
функцию в завел себя в тупик.
Ну, так вылазьте!
Поскольку Вы упражняетесь, готовое решение Вам не нужно, а нужна" удочка" - правильно? Окей, держите.
Когда чего-то не понимаете, всегда ставьте кучу Serial.print буквально через строчку и смотрите на состояние своих переменных. Некоторые значения Вас удивят. Например, Вы убедитесь. что у Вас size1 и size2 всегда равны друг другу и не имеют никакого отношения к длинам строк.
Всегда печатайте значения переменных и анализируйте - не работайте вслепую.
функцию в завел себя в тупик.
Ну, так вылазьте!
Поскольку Вы упражняетесь, готовое решение Вам не нужно, а нужна" удочка" - правильно? Окей, держите.
Когда чего-то не понимаете, всегда ставьте кучу Serial.print буквально через строчку и смотрите на состояние своих переменных. Некоторые значения Вас удивят. Например, Вы убедитесь. что у Вас size1 и size2 всегда равны друг другу и не имеют никакого отношения к длинам строк.
Всегда печатайте значения переменных и анализируйте - не работайте вслепую.
Да, я так понял, что в size хранится размер указателя, век живи - век учись) знания за день не даются ведь)
https://goo.gl/HVAHC5
//Да, я так понял, что в size хранится размер указателя
Не совсем правильно, Вы ж еще чегото там делите.
1. Уберите оба size* и все что с ними связано как классово чуждые, завершение строки (и цикла тоже) контролируйте по появлению нуля вместо очередной буквы.
2. В цикле по обнаружению несовпадения сразу return ... Нечего цикл крутить если результат уже ясен.
3. Рассмотрите вариант с использованием указателей. Как правило эффективней.
ПС. Очень правильно что взялись сами написать такую функцию. Часто при работе с строками возникает ситуация требующая выполнения ряда действий: проверить на недопустимый символ, заменить нижний регистр на верхний, сравнить строки (иногда по сложным условиям частично совпадающие), найти положение некоторого символа-разделителя и пр. Их до чертиков. Как пишет полный лошара? - он юзает String, оно тормозит память жрет и падает. Продвинутый чел пользует strcmp, strlen и прочую стандартную лабутень. Оно работает но не так быстро, как возможно. Потому как в каждой стандартной функции будет свой цикл перебора символов в строке и сколько функций вызвали - столько раз по строке пробежатся надо. А вот в самописном цикле можна за один раз выполнить несколько действий сразу, что дает максимальную скорость. По умному - однопроходный алгоритм получите. Так что дерзайте, оно вознаградится.
https://goo.gl/HVAHC5
Что значит "лучшую". В каких попугаях измерять лучшесть? Во времени выполнения? В памяти? С строках кода (самая длинная или самая короткая)? В каких-то ещё ресурсах?
И даже если фиксировать попугаев, всё равно "лушего" (не в смысле лучше данного, а самого лучшего) не бывает, если не оговоаривать специфику задачи. Например, если критерий лучшести время сравнения, то очень важен вопрос "какие строки (по длине) ожидаются?". Обычно из существа задачи это понятно, и чтобы написать лучшую функцию это надо знать. Функция заточенная под строки в единицы-десятки байтов будет одна, а под мегабайты - совсем другая. И каждая на своей поляне обставит другую.
ЕвгенийП, вот и не надо так нервничать. Каждый выбирает для себя ... https://www.youtube.com/watch?v=Ygkr-Iw6Mb8
А с чего Вы взяли, что я нервничаю? Наоборот, у меня прекрасное настроение, вот и тянет на философские беседы. Или у Вас настроение паршивое и я не вовремя под руку, ну тогда извините.