Не работает условие if после разбиения строки
- Войдите на сайт для отправки комментариев
Пнд, 26/01/2015 - 23:50
char* str = "GET file";
str = strtok(str, " ");
Serial.println(str);
if (str == "GET") Serial.println("!");
Не работает условие if после разбиения строки, хотя на указателе str лежит "GET"
char * str = "GET file"; if (strncmp(str,"GET",3) != -1) Serial.println("!");а вы сравниваете 2 указателя: адрес переменной str с адресом временной переменной по которому лежит"GET". Адреса то разные всегда будут.
в этом условии
(str =="GET") у вас происходит неявное преобразование типов, тип char* преобразуется в int после чего идет сравнение чиселв языке Си/С++ оператор == применяется только для численных типов. Для строк нужно использовать функции типа strcmpв этом условии
(str =="GET") у вас происходит неявное преобразование типов, тип char* преобразуется в int после чего идет сравнение чиселСтрого говоря, не происходит. Указатель на char (по-другому - char*) - вполне стандартный сишный тип, и операции ==, <, > для него определены. И операции сложения/вычитания ( +, - ) тоже, только не со вторым указателем, а с целым числом.
Но по смыслу - да, указатель, физически, это просто адрес в памяти. И в этом случае адреса действительно не равны.
в языке Си/С++ оператор == применяется только для численных типов.Опять же, зачем так категорично! :)
Язык C++ хорош тем, что его можно "на ходу" обучать операторам, которых он ещё не знает.
Тот же тип String, для примера. Для него операция сравнения будет выполняться вполне корректно.
String str = "GET"; if (str == "GET") Serial.println("!");Правда, опять не проверял, но надеюсь не ошибся.
-------
Upd: Наврал немного. Операция вычитания ( - ) для двух указателей тоже определена.
char * str = "GET file"; if (strncmp(str,"GET",3) != -1) Serial.println("!");А попробуйте так - сравнится или нет? :)
char * str = "SET file"; if (strncmp(str,"GET",3) != -1) Serial.println("!");Строго говоря, не происходит.
строго говоря происходит. адрес не является примитивным типом, а сводится к двухбайтовому целому
Тот же тип String, для примера. Для него операция сравнения будет выполняться вполне корректно.
любые слова вырванные из контекста можно оспорить. При чем здесь String? Выше речь исключительно о char* и в коде выше нет перегрузки опрераторов, на которые вы ссылаетесь
адрес не является примитивным типом, а сводится к двухбайтовому целому
Ну так и попробуйте, например, какому-нибудь целому присвоить значение указателя.
Или каким-нибудь if-ом сравнить указатель с int-ом.
Думаете, выполнит за вас компилятор такое же неявное преобразование типов?
При чем здесь String? Выше речь исключительно о char*
Речь шла о языке C/C++ - "в языке Си/С++ оператор == применяется только для численных типов" -
поэтому я и решил уточнить, чтобы не вводить в заблуждение начинающих программистов.
И уж никак не для дого чтоб с кем-то "посраццо". Извините, если что не так.
ннт смысла спорить, неявное преобразование упоминалось для правильного понимания механизма. Сравнивать можно указатели на переменные разного типа именно потому, что для оператора сравнения они все преобразуются к целому
мне стоило указать, что приведенное правило действительно именно для типа char*, тогда наверно не было бы повода спорить) я приводил его именно в контексте, но это видимо не очевидно
Да говорю же - я тоже спорить особо не собирался.
Так, тянет что-то иногда поумничать - не могу с собой бороться. :)
char* str = "Get file"; str = strtok(str, " "); Serial.println(str); if (str == "Get file") Serial.println("!");Скажите, а почему тогда отрабатывает данное условие?
Вот что лежит по адресу str после char* str = "Get file";
А после str = strtok(str, " ");
Т.е. код 32 (пробел) в строке 3 был заменен на 0, указатель остался на строке 0
Тогда фактически мы имеем аналог команды char* str = "Get";
Но, как я писал выше, данный указатель продолжает считать что у него в памяти лежит "Get file"
срабатывание условия if (str == "Get file") Serial.println("!"); тому подтверждение
зы.str = strtok(str, " "); можно было написать наверное просто strtok(str, " ");, результат тот же
За strncmp спасибо, работает
вам больше подходит strcmp, версия с буквой n - strncmp проверяет не полную строку, а указанное число символов. Если проверяется вся строка, то нет смысла указывать число символов
(str =="Get file")возможно срабаывает по тому, что компилятор сделал оптимизацию и на строек 1 и 4 присвоил адрес одной и той же строки, отсюда равенство адресов и срабатывание условиявам больше подходит strcmp, версия с буквой n - strncmp проверяет не полную строку, а указанное число символов. Если проверяется вся строка, то нет смысла указывать число символов
(str =="Get file")возможно срабаывает по тому, что компилятор сделал оптимизацию и на строек 1 и 4 присвоил адрес одной и той же строки, отсюда равенство адресов и срабатывание условияДа, я разобрался с strncmp, единственное не пойму предложенный выше пример
if (strncmp(str,"GET",3) != -1) Serial.println("!");Почему -1? Сревнение значений 00 и 30 дает результат -3, это же разность кодов в памяти и любое значение отличное от 0 говорит о не совпадении (в моем случае сравнивается 0 и 3, т.е. 48-51=-3). Наверное так правильно:
if (strncmp(str,"GET",3) == 0) Serial.println("!");А по поводу компиляции (str == "Get file"), приму как есть и не буду больше использовать. Спасибо
Я так понима, вы хотите чего то там парсить. Попробуйте так:
char *keys[]={"GET","POST","HTTP","RECV","\0"}; //ключевые слова, последняя содержит первым символом 0 int strKeys(char *str) // str строка образец, где мы ищем ключевое слово { int i=0; while(keys[i][0]) { if (!strcmp(str,keys[i])) return(i); //если строки совпали, то выходим из функции с номером совпавшего ключа } return(-1); // если цикл закончился то выходим с -1 это значит ни одно ключевое слово не совпало } switch(strKeys(mister)) { case 0: ........ break; // здесь обрабатываем GET case 1: ........ break; // здесь обрабатываем POST case 2: ........ break; // здесь обрабатываем HTTP case 3: ........ break; // здесь обрабатываем RECV case -1: ......... break; //// здесь вызов если ниодно не совпало }У вас тут i++ наверное в цикле должно быть, но суть понятна. Пример хороший, возмем на вооружение. Спасибо
Да писал на скорую руку, в строке 9 должно быть i++