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

Popular posts from this blog

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -

python - Error while using APScheduler: 'NoneType' object has no attribute 'now' -