Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. basic question

basic question

Scheduled Pinned Locked Moved C / C++ / MFC
questionc++helptutoriallearning
8 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    Hi all!! I'm learning C++ and there I'd like somebody to tell me how to properly use the class CString. The problem is that I've a lot of problems with it, when I'm using different CString vars sometimes they screw each others' values. I've noticed that using a property called GetBuffer and ReleaseBuffer, they get fixed. Could somebody tell me the use of that properties and which is the difference between using MyCStringVar.GetBuffer(iBufferLength) and (LPTSTR)(LPCTSTR)MyCStringVar ?? As far as I know they both return a pointer to the string. I know it might be a basic question but if somebody could answer it I'd really appreciate it, thanks.

    L X 2 Replies Last reply
    0
    • L Lost User

      Hi all!! I'm learning C++ and there I'd like somebody to tell me how to properly use the class CString. The problem is that I've a lot of problems with it, when I'm using different CString vars sometimes they screw each others' values. I've noticed that using a property called GetBuffer and ReleaseBuffer, they get fixed. Could somebody tell me the use of that properties and which is the difference between using MyCStringVar.GetBuffer(iBufferLength) and (LPTSTR)(LPCTSTR)MyCStringVar ?? As far as I know they both return a pointer to the string. I know it might be a basic question but if somebody could answer it I'd really appreciate it, thanks.

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      If you don't need to modify the strings contents then use the (LPTSTR)(LPCTSTR) cast. If you want direct access to the CString buffer (so you can modify it) then use GetBuffer.

      L 1 Reply Last reply
      0
      • L Lost User

        If you don't need to modify the strings contents then use the (LPTSTR)(LPCTSTR) cast. If you want direct access to the CString buffer (so you can modify it) then use GetBuffer.

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        The problem I had is that If I used this code: CString MyString; mFile->Read((LPTSTR)(LPCTSTR)MyString, iMyLength); MyString.Replace("something", AnotherStringWhichIsAMemberVarOfTheClass); When reading the file, the var AnotherStringWhichIsAMemberVarOfTheClass got screwed it's value with what I wanted to read (from the file). Then, by using the Try-All-The-Methods-Of-The-Class solution I noticed that If I wrote: CString MyString; mFile->Read(MyString.GetBuffer(iMyLength), iMyLength); MyString.ReleaseBuffer(); MyString.Replace("something", AnotherStringWhichIsAMemberVarOfTheClass); Everything went right, but I still don't understand why. I'm modifying MyString's content and you've told me that then it'd be better to use GetBuffer(), but contents of AnotherString(...) get screwed when reading the file and before modifying it. Could you tell me why ???? Thanks for everything.

        A M P 3 Replies Last reply
        0
        • L Lost User

          The problem I had is that If I used this code: CString MyString; mFile->Read((LPTSTR)(LPCTSTR)MyString, iMyLength); MyString.Replace("something", AnotherStringWhichIsAMemberVarOfTheClass); When reading the file, the var AnotherStringWhichIsAMemberVarOfTheClass got screwed it's value with what I wanted to read (from the file). Then, by using the Try-All-The-Methods-Of-The-Class solution I noticed that If I wrote: CString MyString; mFile->Read(MyString.GetBuffer(iMyLength), iMyLength); MyString.ReleaseBuffer(); MyString.Replace("something", AnotherStringWhichIsAMemberVarOfTheClass); Everything went right, but I still don't understand why. I'm modifying MyString's content and you've told me that then it'd be better to use GetBuffer(), but contents of AnotherString(...) get screwed when reading the file and before modifying it. Could you tell me why ???? Thanks for everything.

          A Offline
          A Offline
          Alvaro Mendez
          wrote on last edited by
          #4

          OK, it's very simple: CString internally holds a buffer of characters. From our standpoint (programmers using the CString class who don't know exactly how it works) CString's buffer grows/shrinks based on its contents. In the first scenario (the one that breaks) you instanciate a CString object (MyString) using its default constructor. This means that it's empty -- it's got an empty buffer. Then you read the file and try to copy its characters into the empty CString object. Since it's got an empty buffer, you end up inadvertently copying the characters to whatever memory is adjacent to it. So you basically overwrite memory which you hadn't allocated for that purpose. This is very bad, as you noticed. In the second scenario, you call GetBuffer to not only return a writable buffer (LPTSTR), but you also tell the object to allocate iMyLength bytes for you to copy into. After reading from the file, you tell the CString object that you're done using the buffer (ReleaseBuffer) and that it should clean it up (find the terminating null character) and make the object ready for use. I hope this is clear to you, but let me just say that usually if you have to do nasty casting like (LPTSTR)(LPCTSTR)MyString, it's a sign that something's not quite right. You should never do that with a CString object unless you're certain that its buffer won't be changed (ie., you're passing a CString object to poorly written code that should have used LPCTSTR instead of LPTSTR). The general rule is: if the function takes an LPCTSTR (or const char*), use the object directly (no casting needed). If the function takes an LPTSTR (or char*), use GetBuffer/ReleaseBuffer. Regards, Alvaro

          1 Reply Last reply
          0
          • L Lost User

            The problem I had is that If I used this code: CString MyString; mFile->Read((LPTSTR)(LPCTSTR)MyString, iMyLength); MyString.Replace("something", AnotherStringWhichIsAMemberVarOfTheClass); When reading the file, the var AnotherStringWhichIsAMemberVarOfTheClass got screwed it's value with what I wanted to read (from the file). Then, by using the Try-All-The-Methods-Of-The-Class solution I noticed that If I wrote: CString MyString; mFile->Read(MyString.GetBuffer(iMyLength), iMyLength); MyString.ReleaseBuffer(); MyString.Replace("something", AnotherStringWhichIsAMemberVarOfTheClass); Everything went right, but I still don't understand why. I'm modifying MyString's content and you've told me that then it'd be better to use GetBuffer(), but contents of AnotherString(...) get screwed when reading the file and before modifying it. Could you tell me why ???? Thanks for everything.

            M Offline
            M Offline
            Masaaki Onishi
            wrote on last edited by
            #5

            Hello, the codegurus around the world.;) One rule is that you had better use MFC as much as possilbe in your code if you want to use CString. If you want to read the content of the file, you can use CStdio calss. Since you use CString value, and want to pass const char* (LPCSTR) of the function, it sometimes waste your code line (GetBuffer...) or the memory. (but, maybe not big deal). However, if we use COM or Unicode, we face this kind of problem so often.:(( The string conversion gives us so much headache. X| Have a nice day!

            -Masaaki Onishi-

            1 Reply Last reply
            0
            • L Lost User

              The problem I had is that If I used this code: CString MyString; mFile->Read((LPTSTR)(LPCTSTR)MyString, iMyLength); MyString.Replace("something", AnotherStringWhichIsAMemberVarOfTheClass); When reading the file, the var AnotherStringWhichIsAMemberVarOfTheClass got screwed it's value with what I wanted to read (from the file). Then, by using the Try-All-The-Methods-Of-The-Class solution I noticed that If I wrote: CString MyString; mFile->Read(MyString.GetBuffer(iMyLength), iMyLength); MyString.ReleaseBuffer(); MyString.Replace("something", AnotherStringWhichIsAMemberVarOfTheClass); Everything went right, but I still don't understand why. I'm modifying MyString's content and you've told me that then it'd be better to use GetBuffer(), but contents of AnotherString(...) get screwed when reading the file and before modifying it. Could you tell me why ???? Thanks for everything.

              P Offline
              P Offline
              peterchen
              wrote on last edited by
              #6

              (edited) Alvaro's explanation points to the reason. But note that even the following won't work: CString a = "Ophelia"; CString b = a; // *1* strcpy((LPTSTR)(LPCTSTR) b, "Hamlet"); // *2* will change a and b, because: CString uses a "copy on write" mechanism. At line *1*, b will reference the same string buffer as a. Only when you change one of the strings, an actual copy is made. *2* now modifies the shared string buffer without CString having any chance of knowing it. Hence no copy, hence a shared buffer gets modified. ----------------------- CString doesn't have a cast to LPTSTR for a reason. And blindly casting to LPTSTR is definitely not a good idea. Peter

              L 1 Reply Last reply
              0
              • L Lost User

                Hi all!! I'm learning C++ and there I'd like somebody to tell me how to properly use the class CString. The problem is that I've a lot of problems with it, when I'm using different CString vars sometimes they screw each others' values. I've noticed that using a property called GetBuffer and ReleaseBuffer, they get fixed. Could somebody tell me the use of that properties and which is the difference between using MyCStringVar.GetBuffer(iBufferLength) and (LPTSTR)(LPCTSTR)MyCStringVar ?? As far as I know they both return a pointer to the string. I know it might be a basic question but if somebody could answer it I'd really appreciate it, thanks.

                X Offline
                X Offline
                Xian
                wrote on last edited by
                #7

                Read this : http://www.codeproject.com/string/cstringmgmt.asp ---- Xian

                1 Reply Last reply
                0
                • P peterchen

                  (edited) Alvaro's explanation points to the reason. But note that even the following won't work: CString a = "Ophelia"; CString b = a; // *1* strcpy((LPTSTR)(LPCTSTR) b, "Hamlet"); // *2* will change a and b, because: CString uses a "copy on write" mechanism. At line *1*, b will reference the same string buffer as a. Only when you change one of the strings, an actual copy is made. *2* now modifies the shared string buffer without CString having any chance of knowing it. Hence no copy, hence a shared buffer gets modified. ----------------------- CString doesn't have a cast to LPTSTR for a reason. And blindly casting to LPTSTR is definitely not a good idea. Peter

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  thank you all!, nice explanation and I've understood it!

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups