Суббота, 01 Октября 2022, 16:39

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
Форум игроделов » Программирование » C/C++ » Вопрос-Ответ (C++) (Вопросы по С++ задаём здесь.)
Вопрос-Ответ (C++)
KornivalДата: Воскресенье, 04 Сентября 2011, 19:10 | Сообщение # 1
The Witcher
Сейчас нет на сайте
Чтобы не создавать отдельную тему на каждый глупый вопрос, предлагаю задавать их здесь.

Saitei: все вопросы по С задаём в теме Вопрос-Ответ (С). Благодарю за внимание!
AlkoshaДата: Воскресенье, 29 Июня 2014, 23:05 | Сообщение # 1301
участник
Сейчас нет на сайте
Цитата
в качестве аргумента которой передаётся указатель типа char*
goldsphereДата: Воскресенье, 29 Июня 2014, 23:25 | Сообщение # 1302
заслуженный участник
Сейчас нет на сайте
Alkosha,
string s = " Твой путь";
Func(s.c_str());


FinderX - Android Аркада

Сообщение отредактировал goldsphere - Воскресенье, 29 Июня 2014, 23:26
AlkoshaДата: Воскресенье, 29 Июня 2014, 23:28 | Сообщение # 1303
участник
Сейчас нет на сайте
хмм.... странный эррор.
Цитата
E:\TURBO\platform3\main.cpp|547|error: invalid conversion from 'const char*' to 'char*' [-fpermissive]|


но мой стринг не как константа объявлен


Сообщение отредактировал Alkosha - Воскресенье, 29 Июня 2014, 23:32
goldsphereДата: Воскресенье, 29 Июня 2014, 23:54 | Сообщение # 1304
заслуженный участник
Сейчас нет на сайте
Попробуй так
Func((char*)s.c_str()); или
Func(const_cast<char*>(s.c_str()));


FinderX - Android Аркада
AlkoshaДата: Понедельник, 30 Июня 2014, 14:55 | Сообщение # 1305
участник
Сейчас нет на сайте
Компилит нормально. Но во время выполнения программы крашит.

Код
class myLoadStageFromFile
{
private:
ifstream file;

string input[256];
int i=0;

public:
void open()
{
file.open("maps//level1.lvl", ios::in);
          if (file)
          {
              while (!file.eof())
              {
                  file>>input[i];
                  i++;
              }
              file.close();

              for(int j=0;j<i;j++)
              {
                  cout<<input[j]<<"\n";
              }

          deshifrator();
          }
}

private:
int j=0;
void priemResursov()
{
while(input[j]!="endres")
          {
              tileTex[atoi(input[j].c_str())].load((char*)input[j+1].c_str());
              j+=2;
          }
}
void deshifrator()
{
          for(int j=0;j<i;j++)
          {
              if(input[j]=="res")
              {
                  j++;
                  priemResursov();
              }
          }
}
};


Причём этот участок выполняется
Код
while (!file.eof())
              {
                  file>>input[i];
                  i++;
              }
              file.close();

              for(int j=0;j<i;j++)
              {
                  cout<<input[j]<<"\n";
              }


А вот структура файла *.lvl
Цитата
res
0 img//home2.png
1 img//ground1.png
2 img//zabor1.png
3 img//home1.png
4 img//bus.png
5 img//platform1.png
6 img//tree.png
7 img//gorka.png
8 img//ground2.png
9 img//truba.png
10 img//junk.png
endres


Если функцию tileTex[int].load(char*) напрямую выполнить (безо всяких считываний из файла), то всё ок.

Добавлено (30.06.2014, 13:43)
---------------------------------------------
Кстати, а в каждом элементе string-массива может ли быть символ конца строки в этом случае (\n)?
Если да, то как его избежать. Ведь заношу инфу в стринги таким образом.
file>>input[i];

Добавлено (30.06.2014, 14:55)
---------------------------------------------
а не, всё-таки энд-лайна нет в стрингах.
input[i].length() показывает в консольке ровно то же кол-во символов, сколько и видно их в той же самой консольке невооружённым глазом.


Сообщение отредактировал Alkosha - Понедельник, 30 Июня 2014, 22:19
goldsphereДата: Понедельник, 30 Июня 2014, 20:36 | Сообщение # 1306
заслуженный участник
Сейчас нет на сайте
Alkosha, первое что бросается в глаза, ты не предпринимаешь никаких действий, если файла такого нету, т.е считать ты его не смог, а что-то делать с пустой информацией пытаешься.
Код
private:   
int j=0;

Это как? Разве можно инициализировать переменные в классе сразу после их объявления? Надо сделать конструктор.

tileTex[atoi(input[j].c_str())].load((char*)input[j+1].c_str());

Чему тут изначально равно j? Как я понял нулю, так как до этого ты использовал в циклах локальных переменные j, а глобальная ни как не менялась, вот и получается что хочешь получиться число из "res", а потом ещё и значение по этому индексу. Скорее всего тут и вылетает.


FinderX - Android Аркада

Сообщение отредактировал goldsphere - Понедельник, 30 Июня 2014, 20:38
AlkoshaДата: Понедельник, 30 Июня 2014, 22:35 | Сообщение # 1307
участник
Сейчас нет на сайте
глобальное объявление j тоже не помогло.

Добавлено (30.06.2014, 22:27)
---------------------------------------------
Решил глянуть, что же всё-таки пихается в priemResursov()

Код
void priemResursov()
{
while(input[j]!="endres")
{
  //tileTex[atoi(input[j+1].c_str())].load((char*)input[j+2].c_str());
  j+=2;
  cout<<atoi(input[j+1].c_str())<<" : "<<(char*)input[j+2].c_str()<<"\n";
}
}


Результат:

Добавлено (30.06.2014, 22:31)
---------------------------------------------

Цитата goldsphere ()
первое что бросается в глаза, ты не предпринимаешь никаких действий, если файла такого нету, т.е считать ты его не смог, а что-то делать с пустой информацией пытаешься.

это второстепенное. Ибо до перехода в функцию deshifrator() все считанные строки отображаются в консоли.

Добавлено (30.06.2014, 22:35)
---------------------------------------------
ага.... только щас дошло по скриншотам.
Что в этом цикле он шпарит дальше, чем я расчитывал.

Код
for( j=0;j<i;j++)
{
if(input[j]=="res")
{
priemResursov();
}
}


то есть поначалу он всё как и положено делает, затем не выходит из тела while(input[j]!="endres") продолжает шпарить до какого-то неведомого предела.
goldsphereДата: Вторник, 01 Июля 2014, 05:24 | Сообщение # 1308
заслуженный участник
Сейчас нет на сайте
Так как ты к j прибавляешь 2, то получается так что ты строку Enders просто проскакиваешь мимо и берёшь мусор из памяти

Добавлено (01.07.2014, 05:24)
---------------------------------------------

Цитата Alkosha ()
глобальное объявление j тоже не помогло

Она и так у тебя как член класса была объявлена, т.е по отношению к методам она как бы глобальная, я , просто, неправильно выразился smile


FinderX - Android Аркада

Сообщение отредактировал goldsphere - Вторник, 01 Июля 2014, 05:22
AlkoshaДата: Вторник, 01 Июля 2014, 22:08 | Сообщение # 1309
участник
Сейчас нет на сайте
Изначально итерация индекса стрингов j происходила до вызова метода priemResursov(), но когда я j++ перенёс в этот самый priemResursov(), while перестал перескакивать.
Теперь картинки грузит как и положено... но, теперь застопорился на установке координат этих картинок. Как теперь из стрингов убрать запятые(либо иные разделительные знаки) и разделить на отдельные числа... похоже, плохая затея со стрингами. Нужно наверное посимвольно считывать, и тут же на ходу интерпретировать. Но пока не знаю как.


Сообщение отредактировал Alkosha - Вторник, 01 Июля 2014, 22:09
-l33t-h4xx-Дата: Среда, 02 Июля 2014, 09:56 | Сообщение # 1310
участник
Сейчас нет на сайте
Alkosha, а жахни sscanf'ом (он в cstdio). Если ты можешь гарантировать, что пробелов и других левых символов в строке нет, то как раз самое то:

Код
int a, b, c;

const char *numbers = "100,-200,300";

sscanf(numbers, "%d,%d,%d", &a, &b, &c);
// Теперь a = 100, b = -200, c = 300


Как правильно задавать вопросы

Сообщение отредактировал -l33t-h4xx- - Среда, 02 Июля 2014, 09:57
AlkoshaДата: Среда, 02 Июля 2014, 20:45 | Сообщение # 1311
участник
Сейчас нет на сайте
Спасибо, сей подход прекрасно сработал.
geralexДата: Среда, 09 Июля 2014, 09:52 | Сообщение # 1312
участник
Сейчас нет на сайте
Есть бинарник, написаный на C++, сурсов нету. Подскажите, каким софтом возможно переписать часть данный в нем с добавлением свободных байтов, через обычный hex-редактор (например UltraEdit) не получается добавить, бинарник потом не запускается
OpenGOOДата: Среда, 09 Июля 2014, 12:48 | Сообщение # 1313
почти ветеран
Сейчас нет на сайте
geralex, если что это вопрос не имеет никакого отношения к С++

Мои проекты:
- Свободный и открытый клон World Of Goo
- TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)

[GameMaker: Studio v1.4.9999]
AlkoshaДата: Четверг, 10 Июля 2014, 13:06 | Сообщение # 1314
участник
Сейчас нет на сайте
Так-с. Ресурсы и координаты удалось загрузить.
теперь карту коллизии бы туда же.
А то она до сих пор в исполняемой программе находится.
В следующем виде:
Код
static const int maplen = 20;
char *bitmap[maplen]=  
{  

//и тут фиксированное кол-во строк через запятую "....",

}


Когда построчно то же самое считываю из файла, всё ок.
Затем пытаюсь сконвертить в char* - происходит какая-то ерунда.
В консоли cout отображает всякие кракозябры, после чего выбивает из программы.

Код
void collis()
{
     int mapln=0;
     char *btmap[64];
         j+=1;
while(input[j]!="endcollis")
     {
     btmap[mapln]=(char*)input[j].c_str();
     mapln++;
     j++;
     cout<<mapln<<"  "<<btmap[mapln]<<endl;
     }
}

void deshifrator()
{
     for(int j=0;j<i;j++)
     {
         if(input[j]=="res")
         {
             priemResursov();
         }
           if(input[j]=="l1")
         {
             koordTilesL1();
         }
           if(input[j]=="l2")
         {
             koordTilesL2();
         }
            if(input[j]=="collis")
         {
             collis();
         }



Конкретно вот в этой штуке загвоздка.
Код
btmap[mapln]=(char*)input[j].c_str();

Добавлено (10.07.2014, 11:57)
---------------------------------------------
Содержимое считываемого файла

Добавлено (10.07.2014, 13:06)
---------------------------------------------
input[j] -- массив считанных строк.

goldsphereДата: Четверг, 10 Июля 2014, 23:35 | Сообщение # 1315
заслуженный участник
Сейчас нет на сайте
Alkosha, вылетает сразу или через несколько пароходов по циклу? Проблема явно в выходе за границы массива. Проверь чему равно j, и не больши ли оно чем нужно

FinderX - Android Аркада

Сообщение отредактировал goldsphere - Четверг, 10 Июля 2014, 23:35
OpenGOOДата: Пятница, 11 Июля 2014, 11:51 | Сообщение # 1316
почти ветеран
Сейчас нет на сайте
Цитата Alkosha ()
Конкретно вот в этой штуке загвоздка. Код btmap[mapln]=(char*)input[j].c_str();

Это не следует делать, ты хранишь указатели которыми управляет другой объект, он их может изменить. Надо не указатели сохранять, а массив данных на который ссылается указатель, или на худой конец индексы.

Код
int btmap[64];
...
btmap[mapln] = j;


Вот ещё что, сделай так

Код
btmap[mapln]=(char*)input[j].c_str();
cout<<mapln<<"  "<<btmap[mapln]<<endl;
mapln++;   
j++;


И вообще зачем сразу не сделать так

Код

const int INPUT_SIZE = 256;
string input[INPUT_SIZE];

...

while(j < INPUT_SIZE && input[j]!="endcollis") {   
      cout<<mapln<<"  "<<input[j]<<endl;
      mapln++;
      j++;
}


ведь функция вообще кроме вывода строк ничего не делает.


Мои проекты:
- Свободный и открытый клон World Of Goo
- TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)

[GameMaker: Studio v1.4.9999]


Сообщение отредактировал OpenGOO - Пятница, 11 Июля 2014, 14:28
AlkoshaДата: Пятница, 11 Июля 2014, 22:07 | Сообщение # 1317
участник
Сейчас нет на сайте
Цитата OpenGOO ()
ведь функция вообще кроме вывода строк ничего не делает.


А должна.

Вывести строки я и так без проблем могу.

Ф-ция void collis() должна занести эти строки в char *btmap[64];

Короче, вот внутри программы сейчас такая штука.


Мне надо то же самое, считанное с файла поместить в подобный массив.
Так как я файл уже начал считывать построчно, то и эти строки соответственно нужно каким-то образом впихнуть в область, куда ссылаются указатели.


Сообщение отредактировал Alkosha - Пятница, 11 Июля 2014, 22:08
OpenGOOДата: Суббота, 12 Июля 2014, 00:57 | Сообщение # 1318
почти ветеран
Сейчас нет на сайте
Смотри пример работы с strcpy

Мои проекты:
- Свободный и открытый клон World Of Goo
- TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)

[GameMaker: Studio v1.4.9999]
AlkoshaДата: Суббота, 12 Июля 2014, 10:20 | Сообщение # 1319
участник
Сейчас нет на сайте
Код
  strcpy(btmap[mapln],input[j].c_str());


выбивает из программы. j = 1 (вторая строка файла с информацией карты коллизии)
mapln = 0.
OpenGOOДата: Суббота, 12 Июля 2014, 10:57 | Сообщение # 1320
почти ветеран
Сейчас нет на сайте
Код
char* cstr_copy(const std::string& str)
{
     char * cstr = new char [str.length()+1];
     std::strcpy (cstr, str.c_str());
     return cstr;
}

...

btmap[mapln] = cstr_copy(input[j]);


Только потом не забудь освободить выделенную память.

Советую тебе открыть книгу по с++ и изучить главы работы с массивами и строками.


Мои проекты:
- Свободный и открытый клон World Of Goo
- TrueEngine2D (2D игровой фреймворк основанный на FreeBASIC)

[GameMaker: Studio v1.4.9999]


Сообщение отредактировал OpenGOO - Суббота, 12 Июля 2014, 11:49
Форум игроделов » Программирование » C/C++ » Вопрос-Ответ (C++) (Вопросы по С++ задаём здесь.)
Поиск:

Все права сохранены. GcUp.ru © 2008-2022 Рейтинг