Станд. C++:: строка и ПУСТОЙ символ константы*

Сделать его

с text-align: justify?

Обновление : Nevermind. Это не работает вообще, как я думал.

Обновление 2 : не работает ни в каких браузерах кроме IE прямо сейчас, но CSS3 имеет поддержку этого в форме text-align-last

8
задан pythonic metaphor 12 November 2009 в 18:22
поделиться

7 ответов

Вероятно, лучше всего исправить функции библиотеки C до их пред - нарушение поведения. но, возможно, у вас нет контроля над этой библиотекой.

Второе, что следует учитывать, - это изменить все экземпляры, в которых вы зависите от функций C lib, возвращающих пустую строку, чтобы использовать функцию-оболочку, которая исправит вверх 'указатели NULL:

const char* nullToEmpty( char const* s)
{
    return (s ? s : "");
}

Итак, теперь

std::string imacppstring = somecstylefunction();

может выглядеть так:

std::string imacppstring( nullToEmpty( somecstylefunction());

Если это неприемлемо (это может быть много загруженной работы, но это должно быть единовременное механическое изменение), вы могли бы реализовать «параллельную» библиотеку с теми же именами, что и используемая вами библиотека C lib, с этими функциями, просто вызывающими исходные функции C lib и исправляющими указатели NULL при необходимости. Вам нужно будет поиграть в хитрые игры с заголовками, компоновщиком и / или пространствами имен C ++, чтобы заставить это работать, и это может вызвать путаницу в будущем, поэтому я бы хорошо подумал, прежде чем идти по этому пути .

Но что-то вроде следующего может помочь вам начать:

// .h file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction();
}


// .cpp file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction() {
        const char* p = ::somecstylefunction();

        return (p ? p : "");
    }
}

Теперь вам просто нужно добавить этот заголовок в файлы .cpp, которые в настоящее время вызывают вызов функций C lib (и, вероятно, удалить заголовок для C lib) и добавьте

using namespace clib_fixer;

в файл .cpp, используя эти функции.

Это может быть неплохо . Может быть.

библиотека, имеющая те же имена, что и C lib, которую вы используете в настоящее время, причем эти функции просто вызывают исходные функции C lib и при необходимости исправляют указатели NULL. Вам нужно будет поиграть в хитрые игры с заголовками, компоновщиком и / или пространствами имен C ++, чтобы заставить это работать, и это может вызвать путаницу в будущем, поэтому я бы хорошо подумал, прежде чем идти по этому пути .

Но что-то вроде следующего может помочь вам начать:

// .h file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction();
}


// .cpp file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction() {
        const char* p = ::somecstylefunction();

        return (p ? p : "");
    }
}

Теперь вам просто нужно добавить этот заголовок в файлы .cpp, которые в настоящее время вызывают вызов функций C lib (и, вероятно, удалить заголовок для C lib) и добавьте

using namespace clib_fixer;

в файл .cpp, используя эти функции.

Это может быть неплохо . Может быть.

библиотека, имеющая те же имена, что и C lib, которую вы используете в настоящее время, причем эти функции просто вызывают исходные функции C lib и при необходимости исправляют указатели NULL. Вам нужно будет поиграть в хитрые игры с заголовками, компоновщиком и / или пространствами имен C ++, чтобы заставить это работать, и это может вызвать путаницу в будущем, поэтому я бы хорошо подумал, прежде чем идти по этому пути .

Но что-то вроде следующего может помочь вам начать:

// .h file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction();
}


// .cpp file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction() {
        const char* p = ::somecstylefunction();

        return (p ? p : "");
    }
}

Теперь вам просто нужно добавить этот заголовок в файлы .cpp, которые в настоящее время вызывают вызов функций C lib (и, вероятно, удалить заголовок для C lib) и добавьте

using namespace clib_fixer;

в файл .cpp, используя эти функции.

Это может быть неплохо . Может быть.

эти функции просто вызывают исходные функции C lib и при необходимости исправляют указатели NULL. Вам нужно будет поиграть в хитрые игры с заголовками, компоновщиком и / или пространствами имен C ++, чтобы заставить это работать, и это может вызвать путаницу в будущем, поэтому я бы хорошо подумал, прежде чем идти по этому пути .

Но что-то вроде следующего может помочь вам начать:

// .h file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction();
}


// .cpp file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction() {
        const char* p = ::somecstylefunction();

        return (p ? p : "");
    }
}

Теперь вам просто нужно добавить этот заголовок в файлы .cpp, которые в настоящее время вызывают вызов функций C lib (и, вероятно, удалить заголовок для C lib) и добавьте

using namespace clib_fixer;

в файл .cpp, используя эти функции.

Это может быть неплохо . Может быть.

с этими функциями, просто вызывая исходные функции C lib и исправляя указатели NULL при необходимости. Вам нужно будет поиграть в хитрые игры с заголовками, компоновщиком и / или пространствами имен C ++, чтобы заставить это работать, и это может вызвать путаницу в будущем, поэтому я бы хорошо подумал, прежде чем идти по этому пути .

Но что-то вроде следующего может помочь вам начать:

// .h file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction();
}


// .cpp file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction() {
        const char* p = ::somecstylefunction();

        return (p ? p : "");
    }
}

Теперь вам просто нужно добавить этот заголовок в файлы .cpp, которые в настоящее время вызывают вызов функций C lib (и, вероятно, удалить заголовок для C lib) и добавьте

using namespace clib_fixer;

в файл .cpp, используя эти функции.

Это может быть неплохо . Может быть.

и это может привести к путанице в будущем, поэтому я бы хорошенько подумал, прежде чем идти по этому пути.

Но что-то вроде следующего может помочь вам начать:

// .h file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction();
}


// .cpp file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction() {
        const char* p = ::somecstylefunction();

        return (p ? p : "");
    }
}

Теперь вам просто нужно добавить этот заголовок в файлы .cpp, которые в настоящее время вызывают вызов функций C lib (и, вероятно, удаляют заголовок для C lib), и добавляют

using namespace clib_fixer;

в файл .cpp, используя эти функции.

Это тоже может быть не плохо. Может быть.

и это может привести к путанице в будущем, поэтому я бы хорошенько подумал, прежде чем идти по этому пути.

Но что-то вроде следующего может помочь вам начать:

// .h file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction();
}


// .cpp file for a C++ wrapper for the C Lib
namespace clib_fixer {
    const char* somecstylefunction() {
        const char* p = ::somecstylefunction();

        return (p ? p : "");
    }
}

Теперь вам просто нужно добавить этот заголовок в файлы .cpp, которые в настоящее время вызывают вызов функций C lib (и, вероятно, удаляют заголовок для C lib), и добавляют

using namespace clib_fixer;

в файл .cpp, используя эти функции.

Это тоже может быть не плохо. Может быть.

Это может быть не тоже плохо. Может быть.

Это может быть не тоже плохо. Может быть.

13
ответ дан 5 December 2019 в 06:09
поделиться

Ну, без изменения каждого места, где C ++ std :: string инициализируется непосредственно из вызова функции C (чтобы добавить проверка нулевого указателя), единственным решением было бы запретить вашим функциям C возвращать нулевые указатели.

В компиляторе GCC вы можете использовать расширение компилятора «Условные выражения с пропущенными операндами» для создания макроса-оболочки для вашей функции C

#define somecstylefunction() (somecstylefunction() ? : "")

, но в общем случае я бы не советовал этого.

6
ответ дан 5 December 2019 в 06:09
поделиться

Вы могли бы обернуть все ваши вызовы функций C-stlye примерно так ...

std::string makeCppString(const char* cStr)
{
    return cStr ? std::string(cStr) : std::string("");
}

Затем, где бы у вас ни было:

std::string imacppstring = somecstylefunction(); 

замените его на:

std::string imacppstring = makeCppString( somecystylefunction() );

Конечно, это предполагает, что создание пустой строки является допустимым поведением, когда ваша функция возвращает NULL.

2
ответ дан 5 December 2019 в 06:09
поделиться

Я полагаю, вы могли бы просто добавить функцию-оболочку, которая проверяет значение NULL и возвращает пустой std :: string. Но что еще более важно, почему ваши функции C теперь возвращают NULL? Что означает указатель NULL? Если это указывает на серьезную ошибку, вы можете захотеть, чтобы ваша функция-оболочка генерировала исключение.

Или, чтобы быть в безопасности, вы можете просто проверить NULL, обработать регистр NULL и только затем построить std :: string.

const char* s = somecstylefunction();
if (!s) explode();
std::string str(s);
3
ответ дан 5 December 2019 в 06:09
поделиться

Для переносимого решения:

(a) определите свой собственный строковый тип. Самая большая часть - это поиск и замена по всему проекту - это может быть просто, если это всегда std :: string или большая разовая боль. (Я бы сделал единственное требование, чтобы он заменял Лисковым std :: string, но также создавал пустую строку из нулевого символа *.

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

(b) #define std :: string как ваш собственный строковый тип. Рискованно, не рекомендуется. Я бы не стал Я делаю это, если я не знаю задействованные кодовые базы очень хорошо и сэкономит вам массу работы (и я бы добавил несколько заявлений об отказе от ответственности, чтобы защитить остатки моей репутации;))

(c) Я работал над несколькими такими случаями путем повторного # определения наступательного типа для некоторого служебного класса только с целью включения (так что #define гораздо более ограничен по объему). Однако я не знаю, как это сделать для char * .

(d) Напишите оболочку импорта. Если заголовки библиотеки C имеют довольно регулярный макет и / или вы знаете кого-то, кто имеет некоторый опыт синтаксического анализа кода C ++, вы можете сгенерировать «заголовок оболочки».

(e) попросите владельца библиотеки сделать Значение «пустая строка» настраивается по крайней мере во время компиляции.

2
ответ дан 5 December 2019 в 06:09
поделиться

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

class mystring : public std::string
{
    // ... appropriate constructors are an exercise left to the reader
    mystring & operator=(const char * right)
    {
        if (right == NULL)
        {
            clear();
        }
        else
        {
            std::string::operator=(right);  // I think this works, didn't check it...
        }
        return *this;
    }
};
1
ответ дан 5 December 2019 в 06:09
поделиться

Что-то вроде этого должно решить вашу проблему.

const char *cString;
std::string imacppstring;

cString = somecstylefunction();
if (cString == NULL) {
  imacppstring = "";
} else {
  imacppstring = cString;
}

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

0
ответ дан 5 December 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: