Cannot add two pointers

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

DevX
Сообщения: 4
Зарегистрирован: 20 фев 2005, 16:30

void loading()
{
try
{
Sleep(1000);
Screen.Primary->Text("Loading, please wait",250,220,RGB(255,0,0),0);

//load wave
logo_wav=LWF("data//audio//logo.wav",1);
menu_wav=LWF("data//audio//menu.wav",1);
logo_wav->Play(0);

//load bmp
int h_a=0;
for (int h_l=1000; h_l<1050; h_l++)
{
h[h_a]=SFB("data//bmp//h"+h_l+".bmp");
MessageBox(Window.hWnd,h_l,"Error",IDOK);
h_a+=1;
}
logo.LoadBMP(&Screen,NDXST_SYSMEM,"data//bmp//logo.bmp",true);
logo.SetColorKey(0);
logo.SetTransP(true);
}
catch(...)
{
MessageBox(Window.hWnd,"Loading error.", "Error", IDOK);
PostQuitMessage(0);
}
}

Пишет ошибку
d:\Project\Armagedon\Devloping\main.cpp(87): error C2110: '+' : cannot add two pointers

d:\Project\Armagedon\Devloping\main.cpp(88): error C2664: 'MessageBoxA' : cannot convert parameter 2 from 'int' to 'LPCSTR'


Как лечить? :( :(
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Код: Выделить всё

h[h_a]=SFB("data//bmp//h"+h_l+".bmp"); 
Здесь ты всё в кучу смешал: целое число, строковые константы...
Ты до этого на каком языке программировал?

К тому же С++ не позволяет складывать значения типа const char*. Для этого их нужно преобразовать в какой-нибудь строковый класс.
А переменную h_l тоже нужно преобразовать в строку...

Код: Выделить всё

MessageBox(Window.hWnd,h_l,"Error",IDOK); 
Здесь тоже самое, вместо h_l должен быть строковый параметр.

Ещё непонятно, в какой среде программирования ты это делаешь. Склоняюсь к тому, что это скорее всего C++ Builder. Там для работы со строками есть класс AnsiString. А для преобразования числа в строку есть функция IntToStr().
DevX
Сообщения: 4
Зарегистрирован: 20 фев 2005, 16:30

В Microsoft Visual Studio .NET visual с++.
Если по конкретней то как преобразовать int в LPSTR.
Да да знаю в c++ builder есть IntToStr но как в msvc++.net. ?
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

В С нет строк. Там используют массивы char'ов и функцию sprintf для формирования этих самых массивов.

TCHAR buff[MAX_PATH];
wsprintf(buff,"data//bmp//h%i.bmp",h_l);
h[h_a]=SFB(buff);
2B OR NOT(2B) = FF
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

В стандартной библиотеке С/С++ для этого есть функция itoa() и несколько её разновидностей. Для типа LPCTSTR лучше использовать разновидность этой функции _itot(). Можно воспользоваться функцией форматирования строки sprintf()(для типа LPCTSTR функция _stprintf()). В VC++ на платформе MFC есть класс строки CString. В нём есть метод Format(), который работает аналогично функции sprintf().
Лично я для себя в VC++ сделал небольшой класс, который вызывается, как обычная функция IntToStr().

Код: Выделить всё

class IntToStr
{
	TCHAR szText[16];
public:
	IntToStr(int nValue)
	{
		_itot(nValue, szText, 10);
	}
	operator const TCHAR*()
	{
		return szText;
	}
};

Можешь использовать его у себя в проекте. К примеру:
LPCTSTR s1 = IntToStr(12345);
В результате получишь строку "12345".
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

LPCTSTR s1 = IntToStr(12345);
В результате получишь строку "12345"
А где будет храниться эта строка? В стеке? В куче? В статической памяти? Может еще где нибудь?
2B OR NOT(2B) = FF
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Результат хранится в самом классе в его внутренней переменной szText до тех пор, пока "жив" объект класса IntToStr. А время жизни определяется областью видимости объекта, создаваемого конструктором этого класса. Если этот объект является параметром, передаваемым другой функции, то его время жизни ограничивается временем исполнения соответствующей функции...

____________________________________________________________

Есть так же другой способ формирования строк из переменных разного типа: это класс ostrstream.

ostrstream oss;
int iNum = 12345;
oss << "\\bmp\\h_" << iNum << ".bmp";
oss << '\0'; // завершение строки
LPCSTR s1 = oss.str(); // получение результата

В результате получится строка "\bmp\h_12345.bmp";
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Код: Выделить всё

#include "stdafx.h"

class IntToStr
{
   TCHAR szText[16];
public:
   IntToStr(int nValue)
   {
      _itot(nValue, szText, 10);
   }
   ~IntToStr()
   {
	   std::cout<<"Obj destroyed\n";
   }
   operator const TCHAR*()
   {
      return szText;
   }
}; 

int _tmain(int argc, _TCHAR* argv[])
{
	const TCHAR* str = IntToStr(666);
	std::cout<<str;
}
Запустив этот фрагмент кода можно увидеть, что объект разрушается раньше чем используется указатель str.
2B OR NOT(2B) = FF
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

СПАСИБО ЗА ТЕСТ!
Но данный пример не противоречит сказанному мной ранее.
Действительно, в данном случае функция-деструктор вызывается сразу после конструктора и "формально" объект как бы должен быть уничтожен, однако сам объект при этом не прекращает своё существование, т.к. реального разрушения объекта не происходит.
Иначе если бы мы вызвали метод у несуществующего объекта, программа бы просто рухнула. В данном случае метод operator const TCHAR*() вызывается вполне корректно и возвращает реальный результат.
Но здесь есть одна оговорка: этот объект будет существовать лишь в единственном экземпляре. Если мы напишем

const TCHAR* str1 = IntToStr(555);
const TCHAR* str2 = IntToStr(666);
const TCHAR* str3 = IntToStr(777);

то все три переменные str1, str2, str3 будут указывать на одно и то же значение "777".

В таком случае можно явно объявить переменные как объекты класса:
IntToStr str1(555), str2(666), str3(777);
cout << str1 << str2 << str3;

Либо передавать объекты класса непосредственно в функцию:
// пример функции...
void func1(const char* str1, const char* str2, const char* str3)
{
cout << str1 << str2 << str3;
}
// вызов функции...
func1(IntToStr(555), IntToStr(666), IntToStr(777));

Или например так:
cout << IntToStr(555) << IntToStr(666) << IntToStr(777);

В последних трёх примерах и функция-деструктор будет вызываться "правильно", после вызова метода operator const TCHAR*()
DevX
Сообщения: 4
Зарегистрирован: 20 фев 2005, 16:30

С конвертированием разобрался спасибо всем.
Но проблема теперь такая.

...
TCHAR ch[16];
for (int h_l=1000; h_l<1050; h_l++)
{
h[h_a]=SFB("data//bmp//h//h"+_itoa(h_l,ch,10)+".bmp"); // error C2110: '+' : cannot add two pointers
h_a+=1;
}
...

Пробовал так : SFB((std::string("data//bmp//h//h")+_itoa(h_l,ch,10)+".bmp").c_str()); // ????????????? но увы.
Ответить