west329 0 23 июля, 2009 Опубликовано 23 июля, 2009 (изменено) · Жалоба Изучаю работу в окнах под C++Builder 6, до этого писаль только консольные приложеня. Вопрос следующий, есть масив unsigned char IP[4]; потом на форме есть VCL компонент типа TEdit * EditIP, в поле которого пишется ИП адрес в таком виде - 192.168.0.1 собственно в консольном приложении я делал так scanf("%d.%d.%d.%d", &IP_server[0], &IP_server[1], &IP_server[2], &IP_server[3]); А как такое делается в Builder ? подскажите так не работает sscanf(&IP[0],"%d.%d.%d.%d", Edit_IP->Text); тоесть когда вывожу отладочную информацию то масив IP[] содержит одни нули Memo1->Lines->Add(d_str.sprintf("IP %d.%d.%d.%d", IP[0],IP[1],IP[2],IP[3]) ); для проверки Memo1->Lines->Add(Edit_Login->Text); то ип переносится нормально подскажите что неправильно ? Изменено 23 июля, 2009 пользователем west329_ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 23 июля, 2009 Опубликовано 23 июля, 2009 · Жалоба так не работает sscanf(&IP[0],"%d.%d.%d.%d", Edit_IP->Text); тоесть когда вывожу отладочную информацию то масив IP[] содержит одни нули Естественно, потому что Edit_IP->Text не типа char *. Как превратить String (или что там) в char *, изучайте доку на VCL. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 45 23 июля, 2009 Опубликовано 23 июля, 2009 · Жалоба sscanf(Edit_IP->Text.c_str(), "%d.%d.%d.%d", &IP_server[0], &IP_server[1], &IP_server[2], &IP_server[3]); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 24 июля, 2009 Опубликовано 24 июля, 2009 · Жалоба Вопрос следующий, есть масив unsigned char IP[4]; потом на форме есть VCL компонент типа TEdit * EditIP, в поле которого пишется ИП адрес в таком виде - 192.168.0.1 подскажите что неправильно ? Сначала пользователь заводит в Edit текстовую строку "в таком виде - 192.168.0.1". И здесь ничего руками писать не надо... Далее - текстовая строка представляет уже собой массив. Поэтому делаете строковую переменную String IP и ей присваиваете Edit->Text... Далее смотрите по хелпу, как получить доступ к символам строки. Смотрите функцию поиска символа в строке. Либо вручную перебираете символы и находите первую точку, либо пользуетесь функцией Билдера... У меня на сайте выложен пример софта для работы с JTAG. Там есть файл работы со строками. Все откоментировано достаточно подробно... Удачи! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 24 июля, 2009 Опубликовано 24 июля, 2009 · Жалоба Мне другое интересно - как это по формату %d вводится не в int, а в unsigned char? Я понимаю, что везёт - и LOW ENDIAN (ну об этом действительно практически всегда можно забыть), и после массива unsigned char IP[4] просто случайно оказалось ненужное в данный момент место (а вот это уже "чревато боком" для любого процессора) и его не страшно протереть нулями при работе (s)scanf, но... Непривычно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 45 24 июля, 2009 Опубликовано 24 июля, 2009 · Жалоба Мне другое интересно - как это по формату %d вводится не в int, а в unsigned char? Верное замечание! Формат %d для вывода в char-переменные не годится. А формат %hd далеко не все компиляторы поддерживают. Надежнее, да и ближе к стандарту, завести переменные типа int (хотя бы временные), а том из них скопировать в char. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 6 24 июля, 2009 Опубликовано 24 июля, 2009 · Жалоба Нельзя недооценивать пользователя. Он запросто может ввести в это поле что угодно, вплоть до собственного имени, даты рождения или номера паспорта. Для разбора таких данных sscanf() уже мало пригодна, она больше для неинтерактивных данных, где есть уверенность что нужный формат соблюдается. Нужно проконтролировать что числа находятся в диапазоне 0-255, что между ними действительно только одна точка, что чисел всего четыре, не больше и не меньше, и по любой ошибке выдать осмысленное сообщение. Лучше разбирать строку по частям. Можно просто вручную считывать цифры и превращать их в число или применить функции типа atoi() или strtol(), потом проверить на '.', потом следующее число... Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mdmitry 0 24 июля, 2009 Опубликовано 24 июля, 2009 · Жалоба Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода. И при вводе контролировать правильность ввода по диапазону чисел при уходе фокуса ввода на другой элемент. Нечто аналогичное есть в MFC (Edit). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 24 июля, 2009 Опубликовано 24 июля, 2009 · Жалоба Для разбора таких данных sscanf() уже мало пригодна, она больше для неинтерактивных данных, где есть уверенность что нужный формат соблюдается.Если это разбор конфига - то ничем не отличается от ввода с экрана, может оказаться всё, что угодно. Нужно проконтролировать что числа находятся в диапазоне 0-255, что между ними действительно только одна точка, что чисел всего четыре, не больше и не меньше, и по любой ошибке выдать осмысленное сообщение. Лучше разбирать строку по частям. Можно просто вручную считывать цифры и превращать их в число или применить функции типа atoi() или strtol(), потом проверить на '.', потом следующее число... Ну если опускаться до "а вот восьмым символом строки после второго числа у Вас запятая, а там надо бы точку", то, конечно, со scanf-ом туго. А так - scanf вполне нормальная штука: #include <stdio.h> void scan_ip(const char *str) { unsigned IP[4]; char ch; printf( "`%s' : ", str); int result = sscanf( str, "%u.%u.%u.%u%c", IP, IP+1, IP+2, IP+3, &ch); if( result == 5 ) { printf( "extra character in string\n"); } else if( result < 4) { printf( "not all numbers entered, may be numbers delimited with invalid character\n"); } else if( IP[0] > 255 || IP[1] > 255 || IP[2] > 255 || IP[3] > 255) { printf( "numbers must be in range 0..255\n"); } else { printf( "valid IP = %u.%u.%u.%u\n", IP[0], IP[1], IP[2], IP[3] ); } } int main() { scan_ip( "192.168.0.1" ); scan_ip( "192.168.0" ); scan_ip( "192168.0.1.2" ); scan_ip( "192.168.0.1*" ); scan_ip( "192.168,0.1" ); scan_ip( "-192.168.0.1" ); return 0; } `192.168.0.1' : valid IP = 192.168.0.1 `192.168.0' : not all numbers entered, may be numbers delimited with invalid character `192168.0.1.2' : numbers must be in range 0..255 `192.168.0.1*' : extra character in string `192.168,0.1' : not all numbers entered, may be numbers delimited with invalid character `-192.168.0.1' : numbers must be in range 0..255 Думаю, такой диагностики достаточно и нет смысла врукопашную atoi-чить. Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода.Это другое дело. Заодно можно, как это уже реализовано то там, то сям - при выходе из поля если оно оставлено пустым - занулять. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 25 июля, 2009 Опубликовано 25 июля, 2009 · Жалоба С пробелами хуже... "192. 168. 0.1" указанным фрагментом кода воспринимается нормально. Можно попробовать сначала втащить в промежуточную строку, заодно ограничив длину 15 символов и сделав допустимыми только символы цифр и точку char tmpstr[16]; sscanf( str, "%15[0-9.]s", tmpstr); и дальше разбирать уже tmpstr Но по мере наворачивания изобретательности пользователя и необходимости объяснять ему, где он неправ, разжёвывая до выделения красным мест во введённой строке, может оказаться проще действительно вручную разбирать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew2000 0 25 июля, 2009 Опубликовано 25 июля, 2009 · Жалоба счас уже самолет получится... вопрос был про C++Builder - так почему не воспользоваться его средствами? есть-же не только Edit, но и "MaskEdit" - не помню точно как называется - можно сразу задать допустимый для ввода шаблон. Или что-то типа такого (давно с C++Builder слез): TStringList* Strings = new TStringList(); Strings->CommaText = Edit->Text; /*->CommaText ждет ',' - т.е. нужно задать разделителем точку*/ if(Strings->Count==4) { /*разбор Strings, возможно, через StrToInt() или ->AsInteger*/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
west329 0 27 июля, 2009 Опубликовано 27 июля, 2009 · Жалоба Или что-то типа такого (давно с C++Builder слез): А чем сейчас пользуетесь если не секрет. Я взял старенький С потомучто ему не нужна NET платформа, Builder потому что экономит львиную часть времени если работать с окнами мелкософта. есть хорошая альтернатива ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew2000 0 27 июля, 2009 Опубликовано 27 июля, 2009 · Жалоба Qt http://www.qtsoftware.com/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 28 июля, 2009 Опубликовано 28 июля, 2009 · Жалоба есть-же не только Edit, но и "MaskEdit" - не помню точно как называется - можно сразу задать допустимый для ввода шаблон. Защита от дурака это хорошо, но пользователь - всегда прав. Поэтому защиту от дурака надо делать после того как пользователь ввел все что хотел и нажал "ОК", а не до. В MaskEdit же эта защита сделана "до". В результате чего, MaskEdit - это неюзабельная вещь. Поди разбери что он (этот MaskEdit) от тебя хочет, и почему проглатывает символы. Кнопки давишь, а ничего не вводится. Фтопку. Если программа не дает пользователю ввести символы которые он хочет ввести, то место такой программе - в корзине. PS: Мелкософт тоже маладцы блин, при конфигурировании TCP/IP если ошибочно задатать octet IP адреса скажем не 30, а 300 - автоматически получим в поле ввода 255. И вместо того чтобы раз нажать del - придется перевводить все число наново. Спрашивается а нафига такой ителлект вводилки нужен? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew2000 0 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба В MaskEdit же эта защита сделана "до". В результате чего, MaskEdit - это неюзабельная вещь. Если мне память не изменяет, то у MaskEdit можно задать обработчик события неправильного ввода - т.е. можно выводить подсказки, поправлять ввод, ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться