Thread: CFile::Write() problem

  1. #1
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470

    CFile::Write() problem

    Hi

    Code:
    ...
    m_cfile.Open(m_txtfilepath, CFile::modeCreate|CFile::modeWrite, NULL);
    UpdateData(TRUE);
    m_cfile.Write(m_remain, m_remain.GetLength());
    ...
    Above code opens a file and write some data which are in a Edit box (RichEdit) into the file. m_remain is the CString variable which has bind to the Edit box. Problem is that when i write to the file, only the first few chars in the Edit box is written to the file. No problem with m_remain coz when i debug, m_remain shows what's in the edit box correctly. Whatz happening here? Some help please.

    Thanx.
    GameJolt: https://gamejolt.com/@KasunL
    Game Development Youtube:
    https://is.gd/XyhYoP
    Amateur IT Blog: http://everything-geeky.blogspot.com/



    (and, sorry for my amateur English)

  2. #2
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Try casting m_remain to LPCTSTR.
    Code:
    m_cfile.Write( (LPCTSTR)m_remain, m_remain.GetLength() );

  3. #3
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470
    Did that. But still it writes only first 4 chars. im using VS 2005.
    ?
    GameJolt: https://gamejolt.com/@KasunL
    Game Development Youtube:
    https://is.gd/XyhYoP
    Amateur IT Blog: http://everything-geeky.blogspot.com/



    (and, sorry for my amateur English)

  4. #4
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Does it write only the first 4 characters consistently, irregardless of input in the edit box?

  5. #5
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470
    Yes. For example if the edit box contains "CProgramming", then the output would be something like "CPro".
    GameJolt: https://gamejolt.com/@KasunL
    Game Development Youtube:
    https://is.gd/XyhYoP
    Amateur IT Blog: http://everything-geeky.blogspot.com/



    (and, sorry for my amateur English)

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    GetLength() returns the number of characters.
    Write() expects number of bytes.
    1 char = 1 byte
    1 wchar_t = 2 bytes

    If for your project, TCHAR = wchar_t, then you're only writing half the number of bytes you should.

    Cast to "LPCSTR" if you're intention is to write a simple ansi text file.

    gg

  7. #7
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470
    Thanx that worked! i did
    Code:
     m_remain.GetLength() * 2)
    and it worked. Though casting to LPCSTR gave an error.
    GameJolt: https://gamejolt.com/@KasunL
    Game Development Youtube:
    https://is.gd/XyhYoP
    Amateur IT Blog: http://everything-geeky.blogspot.com/



    (and, sorry for my amateur English)

  8. #8
    Android geek@02's Avatar
    Join Date
    Mar 2004
    Location
    Kurunegala Colony, Sri Lanka, Sri Lanka
    Posts
    470
    Another problem. After i write the data, i need to read it back. i did,
    Code:
    ..
    CFile m_cfile;
    char m_txtdata[100000] = "\0";
    m_cfile.Open(m_txtfilepath,CFile::modeRead,NULL);
    m_cfile.Read(m_txtdata, 10000);
    ..
    But the Read function only reads the 1st char of the file now. For example, if i write "Boolean" using the code in previous question, Read() only reads "B". But when i try read a text file which isn't written by this program, it reads the entire file correctly. Why is that?
    Thx.
    GameJolt: https://gamejolt.com/@KasunL
    Game Development Youtube:
    https://is.gd/XyhYoP
    Amateur IT Blog: http://everything-geeky.blogspot.com/



    (and, sorry for my amateur English)

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Handy little trick I use....

    Code:
    // return the byte size of a wide string
    INT StrSize(PTCHAR Str)
      { return (wcslen(Str) * sizeof(TCHAR)) + sizeof(TCHAR); }
    This returns the number of bytes, including the trailing nulls, to write to a file.

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> return (wcslen(Str) * sizeof(TCHAR)) + sizeof(TCHAR);
    You should use _tcs[c]len() to get the length of a TCHAR string.

    Writing TCHAR's to a file doesn't really make sense, unless you really intend to tie the format/encoding of the file to your project settings.

    >> But the Read function only reads the 1st char of the file now.
    It's reading more, you just don't "see" it because every other byte is 0. You wrote wchar_t's, and are reading char's.

    Just write and read char's:
    Code:
    CStringA ansi_str = m_remain;
    // write ansi_str
    gg

  11. #11
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by Codeplug View Post
    GetLength() returns the number of characters.
    Write() expects number of bytes.
    That's confusing, because MSDN says that GetLenght() returns the number of bytes.

  12. #12
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by msh View Post
    That's confusing, because MSDN says that GetLenght() returns the number of bytes.
    A "Character" isn't always a single byte.

    Ascii or Ansi characters are single bytes.
    The word "HELLO" in standard ascii representation would be:
    ox48,0x45,0x4c,0x4c,ox45.

    Unicode has several variants but the most common is a 2 byte character.
    The word "HELLO" in unicode would look like this...
    ox48,0x00,0x45,0x00,0x4c,0x00,0x4c,0x00,ox45,0x00.

    Needless to say these are not interchangeable formats.

    Also the GetLength function you found is part of the C++ CString unit which will not work in C.

    Fixing my mistake from above, this will work...
    Code:
    #include <windows.h> 
    
    // return the byte size of a wide string
    INT StrSize(PTCHAR Str)
      { return (lstrlen(Str) * sizeof(TCHAR)) + sizeof(TCHAR); }
    lstrlen() is a Windows API call that returns the correct number of characters in a string.
    TCHAR is a windows typedef that will correctly hold either ansi or unicode characters
    Both respond to #define UNICODE in your project files, so that StrSize will always return the correct number of bytes to write.

  13. #13
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> ... MSDN says that GetLenght() returns the number of bytes.
    Yeah, that's bad VS 6.0 documentation. But they did get it right in one spot:
    http://msdn.microsoft.com/en-us/libr...8VS.60%29.aspx

    VS 2005 Docs: http://msdn.microsoft.com/en-us/libr...8VS.80%29.aspx

    gg

  14. #14
    Novice
    Join Date
    Jul 2009
    Posts
    568
    Quote Originally Posted by CommonTater View Post
    A "Character" isn't always a single byte.
    I'm well aware of that.

    Quote Originally Posted by Codeplug
    Yeah, that's bad VS 6.0 documentation.
    Damn. Inaccurate documentation is soo frustrating.

  15. #15
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Quote Originally Posted by Codeplug
    GetLength() returns the number of characters.
    Write() expects number of bytes.
    "Number of characters" isn't even accurate. It should be "number of CHAR's or number of WCHAR's".

    A multi-byte codepage can have several bytes per "glyph", and a Unicode grapheme (jargon for glyph) can be made up of more than one code-point. And since Windows uses UTF16LE encoding (WCHAR = 2-bytes), there can be more than one WCHAR per code-point.

    >> You should use _tcs[c]len() to get the length of a TCHAR string
    Using _tcsclen() would be a mistake, since that can map to _mbslen(), which doesn't necessarily return the number of char's/bytes, as intended.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM