<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code Library &#187; CString</title>
	<atom:link href="http://www.ucosoft.com/tag/cstring/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ucosoft.com</link>
	<description>Free Source Code and Program Tips</description>
	<lastBuildDate>Mon, 19 Jul 2010 04:51:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>sscanf with CString</title>
		<link>http://www.ucosoft.com/sscanf-with-cstring.html</link>
		<comments>http://www.ucosoft.com/sscanf-with-cstring.html#comments</comments>
		<pubDate>Tue, 20 Mar 2007 09:01:46 +0000</pubDate>
		<dc:creator>support</dc:creator>
				<category><![CDATA[Win32/MFC]]></category>
		<category><![CDATA[CString]]></category>
		<category><![CDATA[sscanf]]></category>

		<guid isPermaLink="false">http://www.ucosoft.com/archives/76.html</guid>
		<description><![CDATA[Problem: In the C time, we used to use sscanf to read data from string as following: char strUserName[20], strPassword[20]; // if the content of m_recvBuff is &#8220;Microsoft Bill&#8221;. sscanf((const char *)m_recvBuff, &#8220;%s %s&#8221;, strUserName, strPassword); And when you first get CString in sight, you may write the&#160;similar code: CString strUserName, strPassword; // if the]]></description>
			<content:encoded><![CDATA[<p><strong><u>Problem:</u></strong></p>
<p>In the C time, we used to use sscanf to read data from string as following:</p>
<p><coolcode lang="cpp" linenum="no"><br />
char strUserName[20], strPassword[20];<br />
// if the content of m_recvBuff is &#8220;Microsoft Bill&#8221;.<br />
sscanf((const char *)m_recvBuff, &#8220;%s %s&#8221;, strUserName, strPassword);<br />
</coolcode></p>
<p>And when you first get CString in sight, you may write the&nbsp;similar code:</p>
<p><coolcode lang="cpp" linenum="no"><br />
CString strUserName, strPassword;<br />
// if the content of m_recvBuff is &#8220;Microsoft Bill&#8221;.<br />
sscanf((const char *)m_recvBuff, &#8220;%s %s&#8221; , strUserName, strPassword);<br />
</coolcode></p>
<p>Unfortunately, it can not work as you expected and, in most cases, the process will crash.</p>
<p><strong><u>Solution:</u></strong><span id="more-76"></span></p>
<p>First, you should not be using sccanf, since this is not Unicode-aware. You should use _stscanf which allows for Unicode. &nbsp;In addition, it is not a &#8220;safe&#8221; methodology because it can generate buffer overruns.</p>
<p>Second, the problem here is that you are doing something profoundly illegal: you are passing a CString pointer to a call that expects an LPTSTR. &nbsp;You can&#8217;t do this. &nbsp;It won&#8217;t work, and&nbsp;it surprised me that it merely produces an erroneous result instead of crashing with an access fault, heap corruption assert, or some similar fatal situation.</p>
<p>After all, you can use scanf safely, but you should try to use the new _s versions to make them more &#8220;trustworthy&#8221;. &nbsp;Here&#8217;s some info on it: </p>
<p><a href="http://msdn2.microsoft.com/en-us/library/w40768et%28VS.80%29.aspx">http://msdn2.microsoft.com/en-us/library/w40768et(VS.80).aspx</a>  </p>
<p>The problem you&#8217;re having is that you are not actually passing the buffers <br />of the CStrings to the scanf function. Take a look at the GetBuffer() <br />function in CString. &nbsp;Also, this function might be useful to you:
<p><a href="http://msdn2.microsoft.com/en-us/library/k4ftfkd2(VS.80).aspx">http://msdn2.microsoft.com/en-us/library/k4ftfkd2(VS.80).aspx</a>
<p>In additional, You can cast a CString to type LPCTSTR to get read-only access to the contents of the string. &nbsp;However, <br />(1) &nbsp;You can&#8217;t cast a CString to type LPTSTR to get writeable access. &nbsp;You have to do something like call GetBufferSetLength and make sure you set the buffer large enough. <br />(2) &nbsp;In variable parameters to sscanf, you can&#8217;t expect any casting to be done automatically, you have to code the casts.
<p>But if you take enouth care of your code, sscanf may be not necessarily dangerous. You should check the length of the string and make sure you&#8217;ve allocated large enough sizes for your other variables then you won&#8217;t have buffer overruns.  </p>
<p>At last, in MFC, the following code may be the general solution:</p>
<p><coolcode lang="cpp" linenum="no"><br />
CString strUserName;<br />
CString strPassword;<br />
m_recBuff.Trim();  // remove leading and trailing space<br />
int n = m_recvBuff.Find(_T(&#8221; &#8220;));<br />
if(n>0) /* has space */<br />
{<br />
    strUserName = m_recvBuff.Left(n);<br />
    strPassword = m_recvBuff.Mid(n + 1);<br />
    strPassword.Trim();<br />
 }<br />
</coolcode></p>
<p>Unlike sscanf, which should no longer be considered a viable mechanism for any purpose dealing with string outputs, this actually works and is safe. &nbsp;It will not cause a buffer overrun. &nbsp;You should make it a practice to avoid mechanisms that can cause buffer overrun.
<p>The next paragraph&nbsp;is&nbsp;writen by <strong>Joseph M. Newcomer</strong>, as reference.</p>
<p><em>There is no economy in using obsolete and unsafe mechanisms. &nbsp;sscanf is overused and I consider it one of the design errors of the C language. &nbsp;I have never yet found a situation in which I would trust it to do the right thing in the presence of bad input, and the best I can say for it is that it is only suitable for use in the most naively trusting situations possible. &nbsp;I never use it, and I have never used it since I first learned of it. &nbsp;I had, as a beginner, used and trusted such mechanisms in languages I learned in the 1960s, and I quickly learned that such mechanisms are simply not to be trusted. &nbsp;I doubt if I have used such a mechanism since about 1967 or so. &nbsp;It was a bad idea then and it remains a bad idea today. &nbsp;The passage of 40 years does not make a bad idea good. </p>
<p></em></p>

	Tags: <strong><a href="http://www.ucosoft.com/tag/cstring" title="CString" rel="tag">CString</a>, <a href="http://www.ucosoft.com/tag/sscanf" title="sscanf" rel="tag">sscanf</a>, <a href="http://www.ucosoft.com/tag/win32mfc" title="Win32/MFC" rel="tag">Win32/MFC</a></strong><br />

	<ul class="st-related-posts">
	<li><a href="http://www.ucosoft.com/write-and-read-binary-data-in-variant.html" title="Write and read binary data in VARIANT (November 22, 2006)">Write and read binary data in VARIANT</a> (0)</li>
	<li><a href="http://www.ucosoft.com/ucogrid-a-great-grid-control-of-mfc.html" title="ucoGrid, a great grid control of MFC (November 26, 2006)">ucoGrid, a great grid control of MFC</a> (18)</li>
	<li><a href="http://www.ucosoft.com/solution-crash-in-release-build-with-self-defined-message.html" title="Solution: Crash in Release build with self-defined message (November 28, 2006)">Solution: Crash in Release build with self-defined message</a> (0)</li>
	<li><a href="http://www.ucosoft.com/simple-code-to-create-an-emf-or-bitmap-file-from-existed-draw-code.html" title="Simple code to create an EMF or Bitmap file from existed draw code (December 16, 2006)">Simple code to create an EMF or Bitmap file from existed draw code</a> (0)</li>
	<li><a href="http://www.ucosoft.com/simple-cedit-validation.html" title="Simple CEdit Validation (June 27, 2007)">Simple CEdit Validation</a> (0)</li>
	<li><a href="http://www.ucosoft.com/moving-selection-of-clistctrl.html" title="Moving selection of CListCtrl (December 3, 2006)">Moving selection of CListCtrl</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-translate-among-cstringstring-and-char-array.html" title="How to translate among CString,string and char array (June 22, 2007)">How to translate among CString,string and char array</a> (0)</li>
	<li><a href="http://www.ucosoft.com/get-clistctrl-item-text-of-another-process.html" title="How to get ClistCtrl item text of another process (September 24, 2008)">How to get ClistCtrl item text of another process</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-draw-bitmap-from-a-bmp-file.html" title="How to Draw Bitmap from a bmp File? (January 4, 2007)">How to Draw Bitmap from a bmp File?</a> (0)</li>
	<li><a href="http://www.ucosoft.com/how-to-check-whether-the-window-is-in-minimise-or-maximise-mode.html" title="How to check whether the window is in minimise or Maximise mode (March 21, 2007)">How to check whether the window is in minimise or Maximise mode</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://www.ucosoft.com/sscanf-with-cstring.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
