2008-12-15 2 views
2

В настоящее время я работаю в очень простой игре, используя среду C++. Раньше игра была школьным проектом, но теперь, когда я закончил этот класс программирования, я хотел расширить свои навыки и поработать над этим старым заданием.Извлечение струны

Я уже внес много изменений, которым я доволен. Я централизовал все данные в иерархии папок, и я получил код для чтения этих мест.

Однако моя проблема связана с очень фундаментальным недостатком, который меня колотил.

Для того, чтобы получить доступ к данным изображений, которые я использую я использовал код:

string imageLocation = "..\\DATA\\Images\\"; 

string bowImage = imageLocation + "bow.png"; 

Проблема заключается в том, что, когда игрок поднимает предмет на игровом поле моего код должен использовать код :

hud.addLine("You picked up a " + (*itt)->name() + "!"); 

Для печати в командной строке «Вы взяли лук!». Но вместо этого он показывает «Вы выбрали .. \ DATA \ Images \!».

Перед тем, как централизованные мои данные, которые я использовал для использования:

name_(item_name.substr(0, item_name.find('.'))) 

в моем конструктор класса Item, чтобы расколоть имя элемента, чтобы просто что-то вроде лука или свечи. После того, как я изменил структуру своих данных, я понял, что мне придется изменить, как я нарежу имя до одного и того же простого «лука» или «свечи».

Я изменил код выше, чтобы отразить мои изменения в структуре данных, чтобы быть:

name_(item_name.substr(item_name.find("..\\DATA\\Images\\"), item_name.find(".png"))) 

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

Итак, теперь, когда я дал это реальное давнишнее введение в мою проблему, вот мой вопрос.

Как извлечь середину строки между двумя разделами, которые вы не хотите? Также эта средняя часть, которая является вашей целью, имеет неизвестную длину.

Благодарим вас за помощь, которую вы можете дать. Если вам нужна дополнительная информация, пожалуйста, спросите; Я буду более чем счастлив загружать часть или даже весь мой код для получения дополнительной помощи. Еще раз спасибо.

ответ

0

Одна вещь, которая выглядит неправильно, заключается в том, что вторым параметром substr должно быть количество символов для копирования, а не позиция.

1

item_name.find (".. \ DATA \ Images \") вернет индекс, в котором подстрока «.. \ DATA \ Images \» начинается, но похоже, что вам нужен индекс, где он заканчивается, поэтому вы должны добавить длину «.. \ DATA \ Images \» к индексу, возвращаемому find.

Кроме того, как указал hamishmcn, вторым аргументом substr должно быть количество возвращаемых символов, которое будет индексом, где «.png» начинается с минуса индекса, где «.. \ DATA \ Images \» заканчивается , Я думаю.

2

Так комбинируя Павла и мои мысли, попробовать что-то вроде этого (с разбивкой по читаемости):

string extn = item_name.substr(item_name.find_last_of(".png")); 
string path = item_name.substr(0, item_name.find("..\\DATA\\Images\\")); 
name_ = item_name.substr(path.size(), item_name.size() - extn.size()); 

Вы могли бы упростить это немного, если вы знаете, что имя элемента всегда начинается с»..DATA "и т. д. (вы можете сохранить его в константе и не искать его в строке).

Редактировать: Измененная часть поиска расширений для использования find_last_of, как предложено EarWicker (это позволяет избежать случая, когда ваш путь включает в себя" .png 'где-то перед расширением)

3

Предполагая, что я правильно вас понимаю, короткая версия вашего вопроса такова: как мне разделить строку, содержащую путь к файлу, чтобы удалить путь и расширение, оставив только «заголовок»?

Вам нужен метод find_last_of. Это позволяет избавиться от пути:

std::size_type lastSlash = filePath.find_last_of('\\'); 
if (lastSlash == std::string::npos) 
    fileName = filePath; 
else 
    fileName = filePath.substr(lastSlash + 1); 

Обратите внимание, что вы можете определить константу, как \\ в случае, если вам необходимо изменить его для других платформ. Не все файловые системы ОС используют \\ для разделения сегментов маршрута.

Также обратите внимание, что вам также необходимо использовать find_last_of для точки расширения, поскольку имена файлов в целом могут содержать точки на всех путях. Только самый последний указывает на начало расширения:

std::size_type lastDot = fileName.find_last_of('.'); 
if (lastDot == std::string::npos) 
{ 
    title = fileName; 
} 
else 
{ 
    title = fileName.substr(0, lastDot); 
    extension = fileName.substr(lastDot + 1); 
} 

См http://msdn.microsoft.com/en-us/library/3y5atza0(VS.80).aspx

3

с использованием файловой системы наддува:

#include "boost/filesystem.hpp" 

namespace fs = boost::filesystem; 

void some_function(void) 
{ 
    string imageLocation = "..\\DATA\\Images\\"; 
    string bowImage = imageLocation + "bow.png"; 
    fs::path image_path(bowImage ); 
    hud.addLine("You picked up a " + image_path.filename() + "!"); //prints: You picked up a bow! 
7

Во всех honeasty, вы, вероятно, приближается это с того конца ,

Ваш класс предметов должен иметь строчный «лук» в частном члене. Функция Item :: GetFilePath будет тогда (во время выполнения) «.. \ DATA \ Images \" + this-> name + ".png".

Основным свойством объекта предметов «лук» является не имя файла bow.png, а факт, что это «лук». Имя файла - это просто производная доверенность.