Поиск:

Ответ в темуСоздание новой темы Создание опроса
> программа на с++ из delphi, с++ 
:(
    Опции темы
denisminb
Дата 5.6.2013, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Добрый день,народ!Извините,может вопрос пустяк,но не могу решить
Возникли проблемы с кодом на с++, хочу перевести с delphi
есть такой код:
Код

type

 PPacket = ^Packet; {Указатель на запись}
 Packet = record    {Запись с данными о пользователе}
  Nick:string;
 end;
....
....
....
....
public
    { Public declarations }
    procedure SendAllClients(Msg:string; Exception:string = '');
...
....

....
....
//функция sendallclients
procedure TfrmServer.SendAllClients(Msg:string; Exception:string='');
var i:Word;
begin
 for i:=0 to ServerSocket1.Socket.ActiveConnections - 1 do
  if (PPacket(ServerSocket1.Socket.Connections[i].Data).Nick <> Exception) then
   ServerSocket1.Socket.Connections[i].SendText(Msg)
end;




делаю так:
Код

struct Packet {
    std::string Nick;
};

typedef struct Packet* PPacket;

//в .h описываю функцию SendAllClients
public:        // User declarations
    __fastcall TForm2(TComponent* Owner);
              void __fastcall SendAllClients(AnsiString Msg,std::string Exception = "");
//далее в основном файле .cpp
void __fastcall TForm2::SendAllClients(AnsiString Msg, string Exception){
int i;
    for (i = 0; i <ServerSocket1->Socket->ActiveConnections-1 ; i++) {
        if (PPacket(ServerSocket1->Socket->Connections[i]->Data).Nick <>Exception) {
            ServerSocket1->Socket->Connections[i]->SendText(Msg);

         }
    }
}

не правильно составлен условный оператор
ошибка [BCC32 Error] server.cpp(53): E2294 Structure required on left side of . or .*

как мне побороть данную проблему?
PM MAIL   Вверх
xvr
Дата 6.6.2013, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Во первых - почему std::string Exception, когда должно быть AnsiString Exception
Во вторых - в отличие от Pascal'я оператор 'не равно' записывается не как '<>', а как '!=' (строка 15)

Добавлено через 1 минуту и 30 секунд
Ну и вместо .Nick должно быть ->Nick (там же)

Добавлено через 2 минуты и 40 секунд
И еще в строке 2 - опять std::string. Их вообще нигде быть не должно

PM MAIL   Вверх
denisminb
Дата 7.6.2013, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(xvr @ 6.6.2013,  10:31)
Во первых - почему std::string Exception, когда должно быть AnsiString Exception
Во вторых - в отличие от Pascal'я оператор 'не равно' записывается не как '<>', а как '!=' (строка 15)

Добавлено @ 10:32
Ну и вместо .Nick должно быть ->Nick (там же)

Добавлено @ 10:34
И еще в строке 2 - опять std::string. Их вообще нигде быть не должно

спасибо,огроменное.
действительно знак перепутал, ансистринг тоже...про ->Nick не знал.
буду знать.
есть ещё такой вопрос, чтение сокета подключившегося клиента,код делфи
Код

procedure TfrmServer.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var Msg:string;
    Cmd:string[4];
    Text:string;
    NewClient:PPacket;
begin
 Msg := Socket.ReceiveText; {Забрать сообщение}
 Cmd := Copy(Msg,1,4);      {Копировать первые 4 символа. Команда состоит из 4-х символов}
 if (Cmd = cmd_Nick) then   {Если это команда с ником, то}
  begin
  {Копируем ник}
    Text := Copy(Msg,Length(cmd_Nick) + 1,Length(Msg) - Length(cmd_Nick));
  {Выделяем память под нового клиента}
    New(NewClient);
  {Записываем его ник}
    NewClient^.Nick := Text;
  {указатель на данные (Data) сокета текущего клиента будет являться адресом выделенной области памяти}
    Socket.Data := NewClient;
  {Добавить в список}
    lstClients.Items.Add(Text);
  {Сообщить что в сети}
    mmoChat.Lines.Add('Клиент ' + Text + ' в сети');
   end
 else
  begin
  {Вывести сообщение}
    mmoChat.Lines.Add('[' + PPacket(Socket.Data).Nick + ']: ' + Msg);
  {Если включена трансляция, послать всем клиентам}
    if chk1.Checked then
      SendAllClients(Msg,PPacket(Socket.Data).Nick);
  end;
end;



сразу возник у меня вопрос, объявления переменных
1) Могу ли заменить на char данном случае?
типа такого:
Код

   AnsiString Msg;
   char Cmd[4];
   char Text;
   PPacket NewClient;

   Msg=Socket->ReceiveText(); //забираем сообщение
   strcpy(Cmd,Msg.c_str()); 

вопрос как скопировать первые 4 символа строки?знаю есть strncpy(r,r1,n)  
если написать так:
Код

strncpy(Cmd,Msg,4);


то ошибки 
Cannot convert 'AnsiString' to 'const char *'
Type mismatch in parameter '__src' (wanted 'const char *', got 'AnsiString')

Добавлено через 1 минуту и 54 секунды
хотя наверно так 
Код

strncpy(Cmd,Msg.c_str(),4);

компилится

Добавлено через 3 минуты и 29 секунд
только скопирует действительно первые 4 символа строки? или нет?
PM MAIL   Вверх
xvr
Дата 8.6.2013, 09:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(denisminb @  7.6.2013,  19:39 Найти цитируемый пост)
1) Могу ли заменить на char данном случае?

Нет. В Pascal это специальный тип (в Builder что что вроде ShortString)

Цитата(denisminb @  7.6.2013,  19:39 Найти цитируемый пост)
только скопирует действительно первые 4 символа строки? или нет? 

Не более 4х

PM MAIL   Вверх
denisminb
Дата 8.6.2013, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(xvr @ 8.6.2013,  09:15)
Цитата(denisminb @  7.6.2013,  19:39 Найти цитируемый пост)
1) Могу ли заменить на char данном случае?

Нет. В Pascal это специальный тип (в Builder что что вроде ShortString)

Цитата(denisminb @  7.6.2013,  19:39 Найти цитируемый пост)
только скопирует действительно первые 4 символа строки? или нет? 

Не более 4х

если можно,то хочу ещё поинтересоваться:
1) 
а если не Builder ?т.е интересует именно С++ компонент.
думал так,что и если писал в делфи 
Код

  Cmd:string[4];
? т.е должно быть в cmd =4 символа строка.
в с++
Код

  char Cmd[4];
 чем плох?

2) 
в делфи описывал команды перед implementation
Код

const
  cmd_GetNick = '#101';
  cmd_Nick = '#102';


в коде использую так:
 
Text := Copy(Msg,Length(cmd_Nick) + 1,Length(Msg) - Length(cmd_Nick))
итд

а) описываю в с++ с помощью (макросов) #define
б) по идее strncpy уже не подходит?
в) вычисление длины строки strlen
как можно переписать?
PM MAIL   Вверх
denisminb
Дата 8.6.2013, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



2 ой пункт,сам прочитал и не совсем понял,что сам хочу.
т.е. 
пункт а)использую с помощью #define, корректно ли или нет?
б) исходя из делфёвой строки 
Код

Text := Copy(Msg,Length(cmd_Nick) + 1,Length(Msg) - Length(cmd_Nick))
 в текст копируется msg с некоего символа по некоторый
на с++ strncpy не прокатит?можно ли другой использовать?или как лучше описать?
в) в делфи/паскаль определяем размер строки с помощью length(),в с++ strlen()?правильно же?
или как Вы бы посоветовали реализовать?
PM MAIL   Вверх
xvr
Дата 8.6.2013, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(denisminb @  8.6.2013,  13:44 Найти цитируемый пост)
а если не Builder ?т.е интересует именно С++ компонент.

В С++ (именно на уровне языка) нет аналога строки из Delphi. Но зато есть реализация этих аналогов из разных библиотек, в частности из stl и vcl. Вторая из них предоставляет полный функциональный аналог строки Delphi (что и не удивительно, т.к. vcl это библиотека из Delphi)
Отсюда следует, что т.к. встроенной сущности строки нет, то на уровне языка это будет представляться чем то другим, точнее каким то классом.

Однако, в С есть встроенный тип строки (char* в виде литеральной константы в кавычках). Но операции, которые поддерживает язык для этой разновидности строки, сильно отличаются от того, что есть в Delphi. Точнее язык не поддерживает для них практически никаких операций.

Цитата(denisminb @  8.6.2013,  13:44 Найти цитируемый пост)
в с++
Код

  char Cmd[4];
 чем плох?
Собственно этим и плох - это строка в понимании чистого С, для нее никаких Delphi like операций не предусмотрено. И все, что делали с ней в Delphi, придется переписать в С на низком уровне.

Цитата(denisminb @  8.6.2013,  13:44 Найти цитируемый пост)
а) описываю в с++ с помощью (макросов) #define

Опять же, это будут чистые С строки, всю работу с ними придется написать заново. Если хотите аналог Delphi, пишите так -
Код

const AnsiString cmd_GetNick("\145"); // 145 in octal = 101
const AnsiString cmd_Nick("\146"); // 146 in octal = 102


Цитата(denisminb @  8.6.2013,  14:34 Найти цитируемый пост)
на с++ strncpy не прокатит?можно ли другой использовать?или как лучше описать?

Вполне подойдет и strncpy. Просто сместите указатель на начало строки.

Цитата(denisminb @  8.6.2013,  14:34 Найти цитируемый пост)
в) в делфи/паскаль определяем размер строки с помощью length(),в с++ strlen()?правильно же?

Зависит от типа строки - для чистых С строк используйте strlen, для AnsiString или std::string - length() (или size())

PM MAIL   Вверх
denisminb
Дата 8.6.2013, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(xvr @ 8.6.2013,  19:01)
Цитата(denisminb @  8.6.2013,  14:34 Найти цитируемый пост)
на с++ strncpy не прокатит?можно ли другой использовать?или как лучше описать?

Вполне подойдет и strncpy. Просто сместите указатель на начало строки.

если честно не понялс указателем,можете показать?если не затруднить на моём примере?
т.е. это 
Код

Text := Copy(Msg,Length(cmd_Nick) + 1,Length(Msg) - Length(cmd_Nick));

PM MAIL   Вверх
denisminb
Дата 8.6.2013, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



и не совсем понял,как Вы привели в соответствие 145=101 и 146=102?
PM MAIL   Вверх
xvr
Дата 8.6.2013, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(denisminb @  8.6.2013,  20:47 Найти цитируемый пост)
если честно не понялс указателем,можете показать?если не затруднить на моём примере?
Код

Text := Copy(Msg,Length(cmd_Nick) + 1,Length(Msg) - Length(cmd_Nick));

Насколько я понял в Msg в начале лежит cmd_Nick, а в Text оно копируется без cmd_Nick (1 символ)
Тогда для обычных С строк это будет так:
Код

char Text[???]; // Тут вместо ??? должна быть реальная длинна буфера
char Msg[???];

strcpy(Text,Msg+1);
собственно это все  smile 

Цитата(denisminb @  8.6.2013,  21:02 Найти цитируемый пост)
и не совсем понял,как Вы привели в соответствие 145=101 и 146=102? 

145 (это в восьмеричной системе счисления) равно 101 (а это в десятичной). В С конструкция "\???" обозначает код символа именно в восьмеричной системе счисления

PM MAIL   Вверх
denisminb
Дата 8.6.2013, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(xvr @ 8.6.2013,  21:23)
Цитата(denisminb @  8.6.2013,  20:47 Найти цитируемый пост)
если честно не понялс указателем,можете показать?если не затруднить на моём примере?
Код

Text := Copy(Msg,Length(cmd_Nick) + 1,Length(Msg) - Length(cmd_Nick));

Насколько я понял в Msg в начале лежит cmd_Nick, а в Text оно копируется без cmd_Nick (1 символ)
Тогда для обычных С строк это будет так:
Код

char Text[???]; // Тут вместо ??? должна быть реальная длинна буфера
char Msg[???];

strcpy(Text,Msg+1);
собственно это все  smile 

Цитата(denisminb @  8.6.2013,  21:02 Найти цитируемый пост)
и не совсем понял,как Вы привели в соответствие 145=101 и 146=102? 

145 (это в восьмеричной системе счисления) равно 101 (а это в десятичной). В С конструкция "\???" обозначает код символа именно в восьмеричной системе счисления

про восьмиричную систему понял,спасибо.Буду знать.
в Msq хранится принятое от подключившегося клиента сообщение, сообщение это ник.
по идее тогда мне не нужно вычислять длины ?или писать тогда так:
Код

strncpy(Text,Msg+1,4);


Добавлено через 1 минуту и 46 секунд
вопрос тогда остается, признак конца строки(завершаюший ноль) нужно учитывать или нет?
PM MAIL   Вверх
xvr
Дата 9.6.2013, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(denisminb @  8.6.2013,  23:12 Найти цитируемый пост)
по идее тогда мне не нужно вычислять длины ?

Не нужно

Цитата(denisminb @  8.6.2013,  23:12 Найти цитируемый пост)
вопрос тогда остается, признак конца строки(завершаюший ноль) нужно учитывать или нет? 

strncpy очень опасная функция. Ей 3м параметром дают не сколько надо скопировать, а длину (в байтах) массива из 1го параметра. Функция работает так же, как strcpy. Но если буфер из 1го параметра переполняется, то функция немедленно прекращает копирование, даже не записав туда завершающий 0. В результате получается невалидная С строка (т.к. она не завершена нулем)

PM MAIL   Вверх
denisminb
Дата 9.6.2013, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(xvr @ 9.6.2013,  09:14)
Цитата(denisminb @  8.6.2013,  23:12 Найти цитируемый пост)
по идее тогда мне не нужно вычислять длины ?

Не нужно

Цитата(denisminb @  8.6.2013,  23:12 Найти цитируемый пост)
вопрос тогда остается, признак конца строки(завершаюший ноль) нужно учитывать или нет? 

strncpy очень опасная функция. Ей 3м параметром дают не сколько надо скопировать, а длину (в байтах) массива из 1го параметра. Функция работает так же, как strcpy. Но если буфер из 1го параметра переполняется, то функция немедленно прекращает копирование, даже не записав туда завершающий 0. В результате получается невалидная С строка (т.к. она не завершена нулем)

ага,я понял,кажется.
Тогда лучше не баловаться с этой функцией,просто в делфи делал так, с помощью функции copy, в принципе понятно,то что из строки копирую с n-го по M символ. я думаю может лучше на клиенте тогда делать проверку на длину строки (ника), чтобы пользователь не мог ввести свой ник более 4 символов.


в делфе выделял память под клиента следующим образом
Код

......
......
NewClient:PPacket;  // Указатель на запись
......
......
New(NewClient);// выдеделение памяти

...
...
//освобождал
dispose(NewClient)
 

в С++
вот думаю,как лучше сделать?
сделал так:

Код

PPacket *NewClient = new PPacket[4];


но здесь же выделяю под структуру,а не под клиента или я ошибаюсь?


PM MAIL   Вверх
xvr
Дата 9.6.2013, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(denisminb @  9.6.2013,  10:40 Найти цитируемый пост)
но здесь же выделяю под структуру,а не под клиента или я ошибаюсь?

У вас PPacket уже указатель. Так что тут вы заказываете массив из 4х указателей на структуру Packet. Сами структуры не создаются.
Если вам нужна 1 структура, то надо делать так
Код

Packet* NewClient = new Packet;



PM MAIL   Вверх
denisminb
Дата 9.6.2013, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 9.6.2012

Репутация: нет
Всего: нет



Цитата(xvr @ 9.6.2013,  11:05)
Цитата(denisminb @  9.6.2013,  10:40 Найти цитируемый пост)
но здесь же выделяю под структуру,а не под клиента или я ошибаюсь?

У вас PPacket уже указатель. Так что тут вы заказываете массив из 4х указателей на структуру Packet. Сами структуры не создаются.
Если вам нужна 1 структура, то надо делать так
Код

Packet* NewClient = new Packet;

спасибо Вам,огроменное!)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0642 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.