新建工程的时候选择:Win32 Console Application

在向导的地方勾选MFC头文件支持,确认即可

等待初始化文件完成后,VS2010会自动打开 项目名.cpp的文件

其中int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])这个相当于main函数

里面的内容全部可以删除,最后加上一句return 0;即可

MFC常用类:CString类

大家使用VS2010的话,可能会见到CStringT,实际上它是一个操作可变长度字符串的模板类。CStringT模板类有三个实例:CString、CStringA和CStringW,它们分别提供对TCHAR、char和wchar_t字符类型的字符串的操作。

char类型定义的是Ansi字符,wchar_t类型定义的是Unicode字符,而TCHAR取决于MFC工程的属性对话框中的Configuration Properties->General->Character Set属性,如果此属性为Use Multi-Byte Character Set,则TCHAR类型定义的是Ansi字符,而如果为Use Unicode Character Set,则TCHAR类型定义的是Unicode字符。

下面就来看一个例子:

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
CString str1(_T("www.jizhuomi.com")); //wcout << str1.GetString() << endl;
cout << str1.GetString() << endl; return 0;
}

  上述的代码,根据字符串创建了一个CString对象,

因为CString本质上是个指针,而且运算符<<没重载CString的输出,所以用CString自带的GetString()成员函数把CString对象转换成一个字符串。但是前面有说过字符串有三种,TCHAR、char和wchar_t。TCHAR是一个三态模式,所以本质上字符串有两种,分别是:char类型定义的是Ansi字符,wchar_t类型定义的是Unicode字符。同时这两种字符串对应的输出函数是不一样的,char对应cout,wchar_t对应wcout。

所以在项目属性中如果把字符集设置为Unicode,那么CString的GetString()得到的就是wchar_t,所以要用wcout输出;如果在项目中把字符集设置为多字节字符集,那么CString的GetString()得到的就是char,所以要用cout输出。

CString转换为char *的方法

CString::GetBuffer函数

LPTSTR GetBuffer( int nMinBufLength );
throw( CMemoryException );

  返回值:一个指向对象的(以null结尾的)字符缓冲区的LPTSTR指针

参数:nMinBufLength  字符缓冲区的以字符数表示的最小容量。这个值不包括一个结尾的null占用的空间

说明: 
此成员函数返回一个指向CString对象的内部字符缓冲区的指针。返回的LPTSTR不是const,因此可以允许直接修改CString的内容。 
如果你使用由GetBuffer返回的指针来改变字符串的内容,你必须在使用其它的CString成员函数之前调用ReleaseBuffer函数。

在调用ReleaseBuffer之后,由GetBuffer返回的地址也许就无效了,因为其它的CString操作可能会导致CString缓冲区被重新分配。 
如果你没有改变此CString的长度,则缓冲区不会被重新分配。 
当此CString对象被销毁时,其缓冲区内存将被自动释放。

注意:如果你自己知道字符串的长度,则你不应该添加结尾的null字符。但是,当你用ReleaseBuffer来释放该缓冲区时,你必须指定最后的字符串长度。

如果你添加了结尾的空字符,你应该给ReleaseBuffer的长度参数传递-1,ReleaseBuffer将对该缓冲区执行strlen来确定它的长度。

CString对象在内存中用一个计数器来维持可用缓冲区的大小

void ReleaseBuffer( int nNewLength = -1 )
{
if( nNewLength == -1 )
{
nNewLength = StringLength( m_pszData );
}
SetLength( nNewLength );
}

  很明显ReleaseBuffer的作用就是更新字符串的长度。 CString内,GetLength获取字符串长度并不是动态计算的,而是在赋值操作后计算并保存在一个int变量内的,当通过GetBuffer直接修改CString时,那个int变量并不可能自动更新,于是便有了ReleaseBuffer.

CString::ReleaseBuffer函数

void ReleaseBuffer( int nNewLength = -1 );

  参数介绍:

nNewLength:
The new length of the string in characters, not counting a null terminator. If the string is null-terminated, the -1 default value sets the CString size to the current length of the string.

这个函数就是把CString::GetBuffer中申请的多余的空间释放到,参数nNewLength指明新的CString的长度(这个值的大小不包含null占用的那个空间)。如果这个string是null结束的,那么nNewLength就可以传递-1作为参数,这样的做就能把CString设置为原始的string的大小,后面再加上一个结束符号null。

Use ReleaseBuffer to end use of a buffer allocated by GetBuffer. If you know that the string in the buffer is null-terminated, you can omit the nNewLength argument. If your string is not null-terminated, then use nNewLength to specify its length. The address returned by GetBuffer is invalid after the call to ReleaseBuffer or any other CString operation.

这句话有点难理解,其实是这个样子的,原先用GetBuffer得到的buffer可能比CString中真实的大小要大的多,然后用一个指针指向这个buffer(GetBuffer返回的指针),同时注意这时的buffer指针和CString的起始地址是一样的。调用ReleaseBuffer后,CString后面多余的空间就通过CString中的表示字符长度的成员变量限制访问了,其实并没有释放内存,这时的buffer指针仍然是可以使用的,你仍然可以通过这个buffer指针访问到GetBuffer时设定的大小的空间。但是要注意,对CString的操作不能使用这个buffer的指针,因为再调用ReleaseBuffer之后,由GetBuffer返回的地址也许就无效了,因为其它的CString操作可能会导致CString缓冲区被重新分配

// example for CString::ReleaseBuffer
CString s;
s = "abc";
LPTSTR p = s.GetBuffer( 1024 );
strcpy(p, "abc"); // use the buffer directly
ASSERT( s.GetLength() == 3 ); // String length = 3
s.ReleaseBuffer(); // Surplus memory released, p is now invalid.
ASSERT( s.GetLength() == 3 ); // Length still 3

  在ReleaseBuffer调用之后不要使用p,因为CString的地址可能因为其他的操作变化了。

实例分析

CString s("abcd"); //创建一个CString对象s,对象的地址是0x0050b3074

int i = s.GetLength(); //s的长度为4,这个值是从CString类的一个int成员变量读取到的
printf("%s\n", s);
printf("s length1 is %d\n", i); LPTSTR p = s.GetBuffer(6); //s的地址发生了变化,0x005b416c,也就是说重新分配了内存,p也指向这片内存,大小为6,里面存的是"abcd",以null结尾
strcpy( p, "123"); //把"123"copy到了这块内存,里面存的是"123",以null结尾
printf("%s\n", s); //打印出来的字符串是"123",以null结尾
int j = s.GetLength(); //虽然新的字符串是"123",但是字符串的长度成员变量没有被更新,所以还是4
printf("s length2 is %d\n", j); s.ReleaseBuffer(); //这里释放多余的空间,同时更新CString的长度成员变量的值为5,这里的释放不是物理上的释放内存,而是用代码控制,这块多余空间仍然是可用的,但是不安全
printf("%s\n", s);
int k = s.GetLength();
printf("s length3 is %d\n", k); strcpy( p, "a1b2c3"); // 这里新指定的字串若为"a1b2c3e"则会在此中断,因为这个空间一开始的时候申请为6个大小,超过6个都是越界的。同时ReleaseBuffer把CString限定为了"123",所以这种方式复制会是CString内部一致性破坏。(Length和真实值不对应)
printf("%s\n", s); //这里还是能通过p改变CString的内容的,但是不要这么做,因为CString的操作函数会改变CString的内存位置,有可能CString已经搬家了,这是p指向的就是垃圾内存。
//同时造成了CString中实际值和表示个数的成员变量不一致。
int m = s.GetLength();
printf("s length4 is %d\n", m);

  通过指针p和字符串s 实行字符串动态增加的效果是完全不一样的,因为字符串s里有很多成员函数为之服务。

CString::GetString函数

这个函数很简单,就是把CString内的字符串转换为const char *,因为这个值是不允许改动的,所以比GetBuffer简单很多。这里就不多说了,只要注意转换后的字符串是char还是wchar_t就可以了。

控制台console使用MFC库函数,Cout输出CString的方法的更多相关文章

  1. 问题解决——cout 输出 CString

    Unicode下 wcout<<strText.GetString()<<endl;

  2. C++中关于string类型究竟能不能用cout输出的问题

    先让我讲下故事哈 一次在MFC中用cout输出一个string类型字符串,编译时出现这样一个错误: error C2679: binary '<<' : no operator defin ...

  3. 浏览器控制台console

    console对象 console对象代表浏览器的JavaScript控制台.虽然它还不是标准,但是各大浏览器都原生支持,已经成为事实上的标准. console对象主要有两个作用: 显示网页代码运行时 ...

  4. 使用Cout输出String和CString对象

    CString和string都是一个类,不同的是CString主要用于MFC或者是ATL编程中,而string则多用于Windows控制台编程中 在实际编程过程中,我们经常用到string或者是CSt ...

  5. 控制台console输出信息原理理解

    Eclipse控制台输出信息的控制 标签: Eclipse控制台输出信息 2015-01-02 14:11 22454人阅读 评论(1) 收藏 举报  分类: Some Tips(15)  版权声明: ...

  6. Visual Studio将std::cout输出到Output窗口

    在debug的时候,输出到Output需要使用OutputDebugString函数,但部分库的log是采用std::cout输出的,需要用控制台(黑窗)程序来查看输出.有没有一种使用GUI和Outp ...

  7. 转发:Chrome 控制台console的用法

    大家都有用过各种类型的浏览器,每种浏览器都有自己的特色,本人拙见,在我用过的浏览器当中,我是最喜欢Chrome的,因为它对于调试脚本及前端设计调试都有它比其它浏览器有过之而无不及的地方.可能大家对co ...

  8. Chrome 控制台 console

    前言 Chrome浏览器我想是每一个前端er必用工具之一吧,一部分原因是它速度快,体积不大,支持的新特性也比其它浏览器多,还有一部分我想就是因为它的控制台功能强大了吧,说它是神器一点也不过分,很方便. ...

  9. [转]Chrome 控制台console的用法

    Chrome 控制台console的用法 下面我们来看看console里面具体提供了哪些方法可以供我们平时调试时使用. 目前控制台方法和属性有: ["$$", "$x&q ...

随机推荐

  1. PCB外形加工

  2. 把WinXP装进内存 性能飚升秒杀固态硬盘

    现在用户新配置的电脑,内存很少有小于2GB的,配置4GB内存的朋友也有不少.容量如此大的内存,我们在使用电脑的日常操作中绝对用不完.而目前制约系统性能最大的瓶颈就是硬盘的传输速度,所以,这里教你怎么把 ...

  3. 漫谈程序猿系列:她发现了一个Bug……

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZm9ydW9r/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...

  4. 关于对象和this、new

    //创建一个猫类 function Cat(name,color,eyeColor){ //上面处Cat首字母大写表示创建一个‘类别’叫Cat类.假如首字母小写cat则是创建一个cat的函数: thi ...

  5. ASP.NET之电子商务系统开发-1(数据列表)

    一.前言 首先声明的是,这是我第一个与别人合作的.net项目,另一个人做的是后台管理,我做的前台,这是一个电子商务的系统,主要实现的功能是查看商品以及购物功能. 二.开始 首先看一下我截取的项目部分商 ...

  6. C++运算符重载为非成员函数

    #include<iostream> using namespace std; class Complex{ public: Complex(double r=0.0,double i=0 ...

  7. ajax 上传图片 并预览

     <img {if !$article[pic]}style="display: none"{/if} width="82" height="6 ...

  8. IWebBrowser隐藏滚动条

    刚才在项目里看到一个IWebBrowser2,竟然需要通过MoveWindow的方式把滚动条遮挡,如果要缩小IWebBrowser2控件的显示大小呢?这种方法至少我用不习惯,起码也得从源头解决这样的问 ...

  9. c++ 简单的词法分析

    scanner.h #include<iostream> #include<fstream> #include<string> using namespace st ...

  10. 数据库水平切分的实现原理解析——分库,分表,主从,集群,负载均衡器(转)

    申明:此文为转载(非原创),文章分析十分透彻,已添加原文链接,如有任何侵权问题,请告知,我会立即删除. 第1章 引言 随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题.对于一个大 ...