c++ - End of WCHAR* contains junk -
i'm working on small project have manage file i/o (this i'm quit new to). i'm using win32 api unicode character-set , therefore store file-data using wide-characters, , strings in program stored using std::wstring. part of function reads , returns strings:
            //get string file , return             //(nchars amount of characters read)             wchar * resultbuffer = new wchar[nchars];             file.read(resultbuffer, nchars);              std::wstring result = resultbuffer;             delete[] resultbuffer;             return result;   however noticed result contains bunch of garbage characters @ end (the entire string read correctly file, garbage characters appended @ end). upon further inspection noticed these characters appear after resultbuffer gets allocated. wouldn't problem if over-written appear appended, , copied result aswell (meaning result gets more elements intended), leads lot of problems using them later. managed fix problem adding it:
            //get string file , return             wchar * resultbuffer = new wchar[nchars];             file.read(resultbuffer, nchars);             std::wstring temp = resultbuffer;             std::wstring result;             (int = 0; < nchars; i++) { //note: shouldn't necessary                  result.push_back(temp.at(i));             }                            delete[] resultbuffer;             return result;   this fixes problem feel though shouldn't needed. suspected might have how read function (std::wifstream::read()) works, looked @ documentation , found no clue. don't have experience using unicode , wide chars might obvious i'm missing, i'm out clue. got ideas? how resultbuffer looks after read() has been called (stackoverflow prints them kind of middle-eastern characters, appear asian ones in visual studio).
- resultbuffer l"\\.\display1﷽﷽☐☐ﰾ헏✀耀☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐☐" wchar_t *
 
edit: remy lebeau , mksteve providing great explanations aswell answers! working code:
            //get string file , return             std::wstring result;             result.resize(nchars);             file.read(&result[0], nchars);             return result;      
you calling std::wstring constructor expects null-terminated wchar_t* string, not null-terminating buffer.  allocate +1 more wchar , set 0:
wchar * resultbuffer = new wchar[nchars+1]; file.read(resultbuffer, nchars);  resultbuffer[nchars] = l'\0';  std::wstring result = resultbuffer; delete[] resultbuffer; return result;   alternatively, if specify buffer length when constructing std::wstring, don't need null terminator:
wchar * resultbuffer = new wchar[nchars]; file.read(resultbuffer, nchars);  std::wstring result(resultbuffer, nchars); delete[] resultbuffer; return result;   either way, should use std::vector manage memory buffer instead of using new[]/delete[] manually:
std::vector<wchar> resultbuffer(nchars+1); file.read(&resultbuffer[0], nchars);  resultbuffer[nchars] = l'\0';  return std::wstring(resultbuffer.data());     std::vector<wchar> resultbuffer(nchars); file.read(&resultbuffer[0], nchars);  return std::wstring(resultbuffer.data(), nchars);   or, can rid of buffer altogether , read directly std::wstring itself:
std::wstring result; result.resize(nchars); file.read(&result[0], nchars); // or result.data() in c++17 return result;      
Comments
Post a Comment