реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Как правильно делается sscanf для TEdit->Text, C++Builder 6
west329_
сообщение Jul 23 2009, 12:08
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Изучаю работу в окнах под 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);
то ип переносится нормально

подскажите что неправильно ?

Сообщение отредактировал west329_ - Jul 23 2009, 12:45
Go to the top of the page
 
+Quote Post
andrew_b
сообщение Jul 23 2009, 13:30
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(west329_ @ Jul 23 2009, 16:08) *
так не работает
Код
sscanf(&IP[0],"%d.%d.%d.%d", Edit_IP->Text);

тоесть когда вывожу отладочную информацию то масив IP[] содержит одни нули
Естественно, потому что Edit_IP->Text не типа char *. Как превратить String (или что там) в char *, изучайте доку на VCL.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jul 23 2009, 13:42
Сообщение #3


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Код
sscanf(Edit_IP->Text.c_str(), "%d.%d.%d.%d", &IP_server[0], &IP_server[1], &IP_server[2], &IP_server[3]);
Go to the top of the page
 
+Quote Post
iosifk
сообщение Jul 24 2009, 04:56
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(west329_ @ Jul 23 2009, 16:08) *
Вопрос следующий, есть масив
Код
unsigned char IP[4];

потом на форме есть VCL компонент типа TEdit * EditIP, в поле которого пишется ИП адрес
в таком виде - 192.168.0.1

подскажите что неправильно ?


Сначала пользователь заводит в Edit текстовую строку "в таком виде - 192.168.0.1". И здесь ничего руками писать не надо...
Далее - текстовая строка представляет уже собой массив. Поэтому делаете строковую переменную String IP и ей присваиваете Edit->Text...
Далее смотрите по хелпу, как получить доступ к символам строки.
Смотрите функцию поиска символа в строке. Либо вручную перебираете символы и находите первую точку, либо пользуетесь функцией Билдера...
У меня на сайте выложен пример софта для работы с JTAG. Там есть файл работы со строками. Все откоментировано достаточно подробно...
Удачи!


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 24 2009, 09:07
Сообщение #5


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Мне другое интересно - как это по формату %d вводится не в int, а в unsigned char?
Я понимаю, что везёт - и LOW ENDIAN (ну об этом действительно практически всегда можно забыть), и после массива unsigned char IP[4] просто случайно оказалось ненужное в данный момент место (а вот это уже "чревато боком" для любого процессора) и его не страшно протереть нулями при работе (s)scanf, но... Непривычно.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jul 24 2009, 09:31
Сообщение #6


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(ReAl @ Jul 24 2009, 12:07) *
Мне другое интересно - как это по формату %d вводится не в int, а в unsigned char?


Верное замечание! Формат %d для вывода в char-переменные не годится. А формат %hd далеко не все компиляторы поддерживают. Надежнее, да и ближе к стандарту, завести переменные типа int (хотя бы временные), а том из них скопировать в char.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Jul 24 2009, 11:21
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Нельзя недооценивать пользователя. Он запросто может ввести в это поле что угодно, вплоть до собственного имени, даты рождения или номера паспорта. Для разбора таких данных sscanf() уже мало пригодна, она больше для неинтерактивных данных, где есть уверенность что нужный формат соблюдается.
Нужно проконтролировать что числа находятся в диапазоне 0-255, что между ними действительно только одна точка, что чисел всего четыре, не больше и не меньше, и по любой ошибке выдать осмысленное сообщение.
Лучше разбирать строку по частям. Можно просто вручную считывать цифры и превращать их в число или применить функции типа atoi() или strtol(), потом проверить на '.', потом следующее число...

Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Jul 24 2009, 11:48
Сообщение #8


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(SSerge @ Jul 24 2009, 15:21) *
Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода.

И при вводе контролировать правильность ввода по диапазону чисел при уходе фокуса ввода на другой элемент. Нечто аналогичное есть в MFC (Edit).


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 24 2009, 21:37
Сообщение #9


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(SSerge @ Jul 24 2009, 14:21) *
Для разбора таких данных sscanf() уже мало пригодна, она больше для неинтерактивных данных, где есть уверенность что нужный формат соблюдается.
Если это разбор конфига - то ничем не отличается от ввода с экрана, может оказаться всё, что угодно.

Цитата(SSerge @ Jul 24 2009, 14:21) *
Нужно проконтролировать что числа находятся в диапазоне 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-чить.

Цитата(SSerge @ Jul 24 2009, 14:21) *
Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода.
Это другое дело.
Заодно можно, как это уже реализовано то там, то сям - при выходе из поля если оно оставлено пустым - занулять.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jul 25 2009, 12:57
Сообщение #10


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



С пробелами хуже... "192. 168. 0.1" указанным фрагментом кода воспринимается нормально.
Можно попробовать сначала втащить в промежуточную строку, заодно ограничив длину 15 символов и сделав допустимыми только символы цифр и точку
Код
char tmpstr[16];
sscanf( str, "%15[0-9.]s", tmpstr);
и дальше разбирать уже tmpstr
Но по мере наворачивания изобретательности пользователя и необходимости объяснять ему, где он неправ, разжёвывая до выделения красным мест во введённой строке, может оказаться проще действительно вручную разбирать.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Jul 25 2009, 19:56
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



счас уже самолет получится...
вопрос был про C++Builder - так почему не воспользоваться его средствами?
есть-же не только Edit, но и "MaskEdit" - не помню точно как называется - можно сразу задать допустимый для ввода шаблон.
Или что-то типа такого (давно с C++Builder слез):
Код
     TStringList* Strings = new TStringList();
     Strings->CommaText = Edit->Text; /*->CommaText ждет ',' - т.е. нужно задать разделителем точку*/
     if(Strings->Count==4) {
         /*разбор Strings, возможно, через StrToInt() или ->AsInteger*/
Go to the top of the page
 
+Quote Post
west329_
сообщение Jul 27 2009, 18:27
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Цитата(Andrew2000 @ Jul 25 2009, 22:56) *
Или что-то типа такого (давно с C++Builder слез):


А чем сейчас пользуетесь если не секрет.
Я взял старенький С потомучто ему не нужна NET платформа, Builder потому что экономит львиную часть времени если работать с окнами мелкософта.

есть хорошая альтернатива ?
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Jul 27 2009, 21:13
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Qt
http://www.qtsoftware.com/
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 28 2009, 00:02
Сообщение #14


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Andrew2000 @ Jul 25 2009, 22:56) *
есть-же не только Edit, но и "MaskEdit" - не помню точно как называется - можно сразу задать допустимый для ввода шаблон.

Защита от дурака это хорошо, но пользователь - всегда прав. Поэтому защиту от дурака надо делать после того как пользователь ввел все что хотел и нажал "ОК", а не до. В MaskEdit же эта защита сделана "до". В результате чего, MaskEdit - это неюзабельная вещь. Поди разбери что он (этот MaskEdit) от тебя хочет, и почему проглатывает символы. Кнопки давишь, а ничего не вводится. Фтопку.

Если программа не дает пользователю ввести символы которые он хочет ввести, то место такой программе - в корзине.


PS: Мелкософт тоже маладцы блин, при конфигурировании TCP/IP если ошибочно задатать octet IP адреса скажем не 30, а 300 - автоматически получим в поле ввода 255.
И вместо того чтобы раз нажать del - придется перевводить все число наново. Спрашивается а нафига такой ителлект вводилки нужен?
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Jul 30 2009, 07:16
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата(defunct @ Jul 28 2009, 04:02) *
В MaskEdit же эта защита сделана "до". В результате чего, MaskEdit - это неюзабельная вещь.

Если мне память не изменяет, то у MaskEdit можно задать обработчик события неправильного ввода - т.е. можно выводить подсказки, поправлять ввод, ...
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 22:06
Рейтинг@Mail.ru


Страница сгенерированна за 0.01506 секунд с 7
ELECTRONIX ©2004-2016