добавление к строке не меняет строковое значение

Я пытаюсь изучить c ++ для проекта, и у меня возникла небольшая проблема с конкатенацией строк.
Мое приложение состоит из самого приложения и статически связанного проекта библиотеки.
В библиотеке я определил тип, представляющий путь в файловой системе, выступающий в качестве оболочки вокруг литерала пути std :: string.
Я определил функцию для объединения пути родительской папки с (предоставленным пользователем) именем самого файла / папки, добавляя при необходимости разделители пути.
Код функции выглядит следующим образом:

std::string normalize(std::string parentPath, const std::string& name) {
if (name.empty()) {
return parentPath;
} else {
parentPath.reserve(parentPath.length()+name.length()+1);
if (*name.begin() != Path::SEGMENT_SEPARATOR) {
parentPath.append(1,Path::SEGMENT_SEPARATOR);
}
if(*name.rbegin() != Path::SEGMENT_SEPARATOR){
parentPath.append(name);
}else{
parentPath.append(name.begin(), --name.end());
}
return parentPath;
}
}

(Путь :: SEGMENT_SEPARATOR — это константный символ ‘/’)

Проблема в следующем: каждый вызов string :: append, похоже, ничего не делает.
Я отладил функцию с помощью gdb, и содержимое parentPath не изменилось.
Я проверил пользовательский ввод, искал ‘/ 0’ или другие недопустимые символы на входе («имя»), но не нашел в этом ничего плохого.

Когда я переместил точно такую ​​же функцию в проект приложения (из проекта библиотеки), она работала, как и ожидалось (с тем же вводом).

Оба проекта скомпилированы с использованием одного и того же набора инструментов (GCC 4.8.1 и используют диалект C ++ 11) и одинаковых параметров компилятора (все предупреждения включены, предупреждений в коде не поступало).
Есть ли в моем коде что-нибудь, что могло бы сломать string :: append таким образом?

РЕДАКТИРОВАТЬ: функция вызывается из:

Path::Path(const Path& parent, const std::string& name) : path_(normalize(parent.path_, name)) { }
Path::Path(const Path& parent, const char* name) : Path(parent, std::string(name)) {}

Который в свою очередь вызывается из (заголовочный файл):

extern const IO::Path CONFIG_PATH;
extern const IO::Path LANGUAGES_PATH;

С определением в файле cpp:

const IO::Path Game::CONFIG_PATH{"conf"};
const IO::Path Game::LOG_PATH{CONFIG_PATH,"log"};

Проверка объекта LOG_PATH показывает его значение элемента path_ как просто «conf» вместо «conf / log», как и ожидалось.
Могу ли я быть уверен, что CONFIG_PATH инициализируется до LOG_PATH, может ли это быть проблемой?

РЕДАКТИРОВАТЬ:
Я прочитал стандарт, и кажется, что вы не можете полагаться на какой-либо порядок инициализации глобальных переменных.
Это означает, что объявления CONFIG_PATH и LOG_PATH, очевидно, являются ошибками, и я, вероятно, должен заключить их в вызов функции следующим образом:

const IO::Path &getConfigPath(){
static IO::Path config{"conf"};
return config;
};

Может ли это быть причиной неудачного добавления строки?

0

Решение

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

std::string normalize(std::string parentPath, const std::string& name)
{
if (name.empty())
return parentPath;
else
{
if (name.front() != Path::SEGMENT_SEPARATOR)
parentPath += Path::SEGMENT_SEPARATOR;

if(name.back() != Path::SEGMENT_SEPARATOR)
parentPath += name;
else
parentPath.append(name.begin(), name.end()-1);

return parentPath;
}
}
2

Другие решения

Вы можете использовать

string str1, str2, strFinal;
strFinal = str1 + "some static string" + str2;

Что я думаю, что вы должны

Просто для справки:

std::string normalize(std::string parentPath, const std::string& name)
{
if (name.empty())
return parentPath;
else
{
if (name[0] != '/')
parentPath += '/';
if(name[name.length()-1] != '/')
parentPath += name;
else
parentPath.append(name.begin(), name.end()-1);
return parentPath;
}
}
2

Вот SSCCE, демонстрирующий, что ваша функция работает правильно. Проблема в коде, который вы есть не показывая нам.

2

Проблема почти наверняка заключается в некоторой проблеме конфигурации (несоответствие в параметрах компилятора, параметрах компоновщика или определениях препроцессора между двумя проектами), поскольку это не происходит, когда я объединяю два проекта в один.
Спасибо за комментарии к функции конкатенации: позже я переписываю ее в более читабельную форму.
Спасибо всем за полезные комментарии.

РЕДАКТИРОВАТЬ: обнаружил проблему.
Препроцессор #define, используемый для включения зависимой от linux реализации некоторых членов Path (в основном функции, создающей новые каталоги и файлы), был включен в основной проект, но не в библиотеку. Это, вероятно, вызвало проблему, когда библиотека была связана. Работает как шарм сейчас.

0
По вопросам рекламы [email protected]