Ломаю голову над простой функцией
- Войдите на сайт для отправки комментариев
Вс, 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
Так не?...
Пробуйте :) .
А вообще, такая форма записи мне кажется совершенно нечитаемой - я бы лучше вместо for в таких конструкциях пользовал бы while. Но это по вкусу. И еще - такой метод предполагает, что строка обязательно заканчивается нулевым символом. Про это вот тут почитать можно: http://arduino.ru/Reference/String.
Так не?...
Так да, просто хотел свое написать)
функцию в завел себя в тупик.
Ну, так вылазьте!
Поскольку Вы упражняетесь, готовое решение Вам не нужно, а нужна" удочка" - правильно? Окей, держите.
Когда чего-то не понимаете, всегда ставьте кучу 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
А с чего Вы взяли, что я нервничаю? Наоборот, у меня прекрасное настроение, вот и тянет на философские беседы. Или у Вас настроение паршивое и я не вовремя под руку, ну тогда извините.