Существует много функций Win32, которые берут адрес буфера, такой как TCHAR[256]
, и запишите некоторые данные в тот буфер. Это могут быть меньше, чем размер буфера, или это может быть весь буфер.
Часто Вы будете называть это в цикле, например, для чтения данных от потока или канала. В конце я хотел бы эффективно возвратить строку, которая имеет полные данные из всех выполненных с помощью итераций вызовов для получения этих данных. Я думал для использования std::string
так как это + =, оптимизирован похожим способом к Java или C# StringBuffer.append()
/StringBuilder.Append()
методы, способствуя скорости вместо памяти.
Но я не уверен как лучше всего co-mingle std::string
с функциями Win32, так как эти функции берут char[]
для начала. Какие-либо предложения?
std::string
имеет функцию c_str()
, которая возвращает эквивалентную строку в стиле Си. (const char *
)
Далее, в std::string
имеется перегруженный оператор присваивания, который принимает на вход строку в Си-стиле.
например Пусть ss
будет экземпляром std::string
и sc
будет строкой в С-стиле, тогда преобразование может быть выполнено как :
ss = sc; // from C-style string to std::string
sc = ss.c_str(); // from std::string to C-style string
UPDATE :
Как указал Майк Уэллер, если макрос UNICODE
определен, то строки будут wchar_t*
, и поэтому вместо них нужно использовать std::wstring
.
, а не STD :: String, я бы предложил использовать STD: : Vector
, И используйте & v.front ()
при использовании v.size ()
. Убедитесь, что имейте пространство уже выделено!
Вы должны быть осторожны с std :: string
и двоичные данные.
s += buf;//will treat buf as a null terminated string
s += std::string(buf, size);//would work
Вам нужен совместимый тип строки: TYPEDEF STD :: BASIC_STRING
- хороший выбор.
Для аргументов только ввода вы можете использовать метод .c_str ().
Для буферов на выбор немного менее четко:
STD :: Basic_String не гарантированно использовать непрерывное хранилище, такое как STD :: Vector. Тем не менее, все реализации STD :: BASIC_STRING, которые я видел, используйте непрерывное хранилище, и комитет по стандартам C ++ рассматривает пропавшую гарантию быть дефектом в стандарте. Дефект был исправлен в черновике C ++ 0x.
Если вы готовы согнуть правила так слегка слегка - без отрицательных последствий - вы можете использовать & (* astring.begin ()) в качестве указателя на буфер TCHR длиной astring.size (). В противном случае вы застряли с std :: Вектор на данный момент.
Вот что стандартный комитет C ++ должен сказать о смежных строковых хранилищах:
не стандартизация этого существующего Практика не дает исполнителей Больше свободы. Мы думали, что это может Десяти лет назад. Но поставщики имеют говорил оба с их Реализации, а со своим голосом на встречах LWG. То Реализации будут смежный независимо от того, какой стандарт говорит. Так что стандарт может также дать строковые клиенты больше дизайна Выбор.
Если аргумент только для ввода, используйте std::string
, как этот
std::string text("Hello");
w32function(text.c_str());
Если аргумент input/output, используйте std::vector
, а не этот:
std::string input("input");
std::vector<char> input_vec(input.begin(), input.end());
input_vec.push_back('\0');
w32function(&input_vec[0], input_vec.size());
// Now, if you want std::string again, just make one from that vector:
std::string output(&input_vec[0]);
Если аргумент только для вывода также используйте std::vector
аналогично этому:
// allocates _at least_ 1k and sets those to 0
std::vector<unsigned char> buffer(1024, 0);
w32function(&buffer[0], buffer.size());
// use 'buffer' vector now as you see fit
Вы также можете использовать std::basic_string
и std::vector
, если это необходимо.
Вы можете прочитать больше по этой теме в книге Effective STL Скотта Мейерса.