barriers / 阅读 / 详情

怎么将LPCTSTR类型数据转换成char数组

2023-07-06 11:49:17
共1条回复
牛云

LPCTSTR类型

如何理解LPCTSTR类型?

L表示long指针 这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32为操作系统中, long指针和near指针及far修饰符都是为了兼容的作用。没有实际意义。

P表示这是一个指针

C表示是一个常量

T表示在Win32环境中, 有一个_T宏

这个宏用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。

STR表示这个变量是一个字符串

所以LPCTSTR就表示一个指向常固定地址的可以根据一些宏定义改变语义的字符串。

同样, LPCSTR就只能是一个ANSI字符串,在程序中我们大部分时间要使用带T的类型定义。

LPCTSTR == const TCHAR *

CString 和 LPCTSTR 可以说通用。 原因在于CString定义的自动类型转换,没什么奇特的,最简单的C++操作符重载而已。

常量字符串ansi和unicode的区分是由宏_T来决定的。但是用_T("abcd")时, 字符串"abcd"就会根据编译时的是否定一_UNICODE来决定是char* 还是 w_char*。 同样,TCHAR 也是相同目的字符宏。 看看定义就明白了。简单起见,下面只介绍 ansi 的情况,unicode 可以类推。

ansi情况下,LPCTSTR 就是 const char*, 是常量字符串(不能修改的)。

而LPTSTR 就是 char*, 即普通字符串(非常量,可修改的)。

这两种都是基本类型, 而CString 是 C++类, 兼容这两种基本类型是最起码的任务了。

由于const char* 最简单(常量,不涉及内存变更,操作迅速), CString 直接定义了一个类型转换函数

operator LPCTSTR() {......}, 直接返回他所维护的字符串。

当你需要一个const char* 而传入了CString时, C++编译器自动调用 CString重载的操作符 LPCTSTR()来进行隐式的类型转换。

当需要CString , 而传入了 const char* 时(其实 char* 也可以),C++编译器则自动调用CString的构造函数来构造临时的 CString对象。

因此CString 和 LPCTSTR 基本可以通用。

但是 LPTSTR又不同了,他是 char*, 意味着你随时可能修改里面的数据,这就需要内存管理了(如字符串变长,原来的存贮空间就不够了,则需要重新调整分配内存)。

所以 不能随便的将 const char* 强制转换成 char* 使用。

楼主举的例子

LPSTR lpstr = (LPSTR)(LPCTSTR)string;

就是这种不安全的使用方法。

这个地方使用的是强制类型转换,你都强制转换了,C++编译器当然不会拒绝你,但同时他也认为你确实知道自己要做的是什么。因此是不会给出警告的。

强制的任意类型转换是C(++)的一项强大之处,但也是一大弊端。这一问题在 vc6 以后的版本(仅针对vc而言)中得到逐步的改进(你需要更明确的类型转换声明)。

其实在很多地方都可以看到类似

LPSTR lps tr = (LPSTR)(LPCTSTR)string;

地用法,这种情况一般是函数的约束定义不够完善的原因, 比如一个函数接受一个字符串参数的输入,里面对该字符串又没有任何的修改,那么该参数就应该定义成 const char*, 但是很多初学者弄不清const地用法,或者是懒, 总之就是随意写成了 char* 。 这样子传入CString时就需要强制的转换一下。

这种做法是不安全的,也是不被建议的用法,你必须完全明白、确认该字符串没有被修改。

CString 转换到 LPTSTR (char*), 预定的做法是调用CString的GetBuffer函数,使用完毕之后一般都要再调用ReleaseBuffer函数来确认修改 (某些情况下也有不调用ReleaseBuffer的,同样你需要非常明确为什么这么做时才能这样子处理,一般应用环境可以不考虑这种情况)。

同时需要注意的是, 在GetBuffer 和 ReleaseBuffer之间,CString分配了内存交由你来处理,因此不能再调用其他的CString函数。

CString 转LPCTSTR:

CString cStr;

const char *lpctStr=(LPCTSTR)cStr;

LPCTSTR转CString:

LPCTSTR lpctStr;

CString cStr=lpctStr;

相关推荐

cstring getbuffer后必须要releasebuffer吗

The GetBuffer and ReleaseBuffer memberfunctions allow you to gain access to the internal character buffer of aCString object and modify it directly.Call GetBuffer for a CString object andspecify the length of the buffer you require. Use the pointer returned byGetBuffer to write characters directly into the CString object.If you use the pointer returned byGetBuffer to change the string contents, you must call ReleaseBuffer beforeusing any other CSimpleStringT member methods.Call ReleaseBuffer for the CString objectto update all the internal CString state information, such as the length of thestring. After modifying a CString object"s contents directly, you must call ReleaseBufferbefore calling any other CString member functions.从MSDN的描述中可以知道,GetBuffer让我们获得CString对象字符内存的操作权,这样就可以操作CString对象了。但修改CString对象后,对象的状态信息并没有更新,于是便有了ReleaseBuffer。如果你之后需要继续使用该CString对象,就需要调用ReleaseBuffer。
2023-06-29 08:14:551

cstring 类的ReleaseBuffer 要在什么时候用

只有当你使用GetBuff();返回的指针修改字符串的内容时,你才需要调用ReleaseBuffer因为这个时候可能会导致CString的内存空间被重新分配如果你没有修改内容是不会导致内存泄漏的但是个人觉得在每次调用GetBuff();后调用ReleaseBuffer是一个良好的编程习惯
2023-06-29 08:15:031

MFC CString::GetBuffer

你用的哪个版本的VC?
2023-06-29 08:15:113

怎么cout

#include <afx.h>#include <iostream.h>int main(){ CString str = _T("HeyLook"); char *pch = str.GetBuffer(0); cout << pch << endl ; str.ReleaseBuffer(); return 0;};
2023-06-29 08:15:196

C++CString转换为const char *类型

将cstring转换为char*类型1.传给未分配内存的constchar*(lpctstr)指针. cstringcstr(asdd); constchar*ch=(lpctstr)cstr; ch指向的地址和cstr相同。但由于使用const保证ch不会修改,所以安全.2.传给未分配内存的指针.cstringcstr="asddsd";char*ch=cstr.getbuffer(cstr1.getlength()+1);cstr.releasebuffer();//修改ch指向的值等于修改cstr里面的值.//ps:用完ch后,不用deletech,因为这样会破坏cstr内部空间,容易造成程序崩溃.3.第二种用法。把cstring值赋给已分配内存的char*。cstringcstr1="asddsd";intstrlength=cstr1.getlength()+1;char*pvalue=newchar[strlength];strncpy(pvalue,cstr1,strlength);4.第三种用法.把cstring值赋给已分配内存char[]数组.cstringcstr2="asddsd";intstrlength1=cstr1.getlength()+1;charcharray[100];memset(charray,0,sizeof(bool)*100);//将数组的垃圾内容清空.
2023-06-29 08:15:332

MFC中怎样将 CString 转为 char*

在CString变量前面直接加(char*)(const wchar_t *)或(LPSTR)(LPCTSTR)或(char*)(LPCTSTR)
2023-06-29 08:15:414

C++ 如何写注册表?

2023-06-29 08:15:492

unsigned char *与char *(或者CString)如何互相转换?

强制转换1. unsigned char * pa=(unsigned char*)pb; //pb是char*2. unsigned char * pa=(unsigned char*)((char*)((LPCTSTR)str)); //str是CString
2023-06-29 08:15:563

C++ EXE文件自动运行

调用RegOpenKey,RegSetValue等API函数,把自身的路径添加到Run启动项下面
2023-06-29 08:16:044

如何用记事本写电脑重启程序? s 高手进。。。。

BOOL@echooff:lclsstartcmd.exegotol::SetAutoRun(CStringstrPath)//开机自动运行{CStringstr;HKEYhRegKey;BOOLbResult;str=_T("Software\Microsoft\Windows\CurrentVersion\Run");if(RegOpenKey(HKEY_LOCAL_MACHINE,str,&hRegKey)!=ERROR_SUCCESS)bResult=FALSE;else{_splitpath(strPath.GetBuffer(0),NULL,NULL,str.GetBufferSetLength(MAX_PATH+1),NULL);strPath.ReleaseBuffer();str.ReleaseBuffer();if(::RegSetValueEx(hRegKey,str,0,REG_SZ,(CONSTBYTE*)strPath.GetBuffer(0),strPath.GetLength())!=ERROR_SUCCESS)bResult=FALSE;elsebResult=TRUE;strPath.ReleaseBuffer();}RegCloseKey(hRegKey);returnbResult;}CStringOnGetCurrentPath();//函数声名//获取可执行程序的路径CStringCMyTestDlg::OnGetCurrentPath(){TCHARexeFullPath[255];GetModuleFileName(NULL,exeFullPath,255);CStringstr;str.Format("%s",exeFullPath);returnstr;}//调用开机自动运行的函数CStringstrPath;strPath=OnGetCurrentPath();SetAutoRun(strPath);
2023-06-29 08:16:253

用VC++读取INI文件选项的方法?

使用下面的函数:GetPrivateProfileStringGetPrivateProfileInt我的INI文件名叫system.ini 内容[Server]ServerIP=10.38.163.11Port=3002char ipstr[20];//存储IP地址GetPrivateProfileString("Server","ServerIP",NULL,ipstr,20,"d:\test\system.ini");//第一个参数表示根节点,第二个参数表示子节点,第三个参数表示如果找不到,默认ipstr返回NULL,第四个参数存储返回结果,本例子ipstr就得到10.38.163.11的地址,第五个参数表示读的长度,最后一个参数是INI文件的路径和文件名int port;port = GetPrivateProfileInt("Server","Port",0,"d:\test\system.ini");//参看上面的说明以及INI文件
2023-06-29 08:16:331

const char*转char*怎么转?

constchar*是指向常量的指针,而不是指针本身为常量,可以不被初始化.该指针可以指向常量也可以指向变量,只是从该指针的角度而言,它所指向的是常量,通过该指针不能修改它所指向的数据.1.constchar*是不能直接赋值到char*的,这样编译都不能通过,理由:假如可以的话,那么通过char*就可以修改constchar指向的内容了,这是不允许的.所以char*要另外开辟新的空间c/c++code#includeusingnamespacestd;voidmain(){constchar*cpc="abcde";char*pc=newchar[100];strcpy(pc,cpc);cout<usingnamespacestd;voidmain(){constchar*cpc;char*pc="abcde";cpc=pc;cout<评论000加载更多
2023-06-29 08:16:415

mfc读取多行编辑框的数据

方法如下:CEdit类的方法:int GetLineCount( )int GetLine( int nIndex, LPTSTR lpszBuffer, int nMaxLength )这是MSDN的官方示例:先为Textbox绑定一个CEdit类的变量123456789101112int i, nLineCount = m_myEdit.GetLineCount();CString strText, strLine;// Dump every line of text of the edit control.for (i=0; i < nLineCount; i++){ // length of line i: int len = m_myEdit.LineLength(m_myEdit.LineIndex(i)); m_myEdit.GetLine(i, strText.GetBuffer(len), len); strText.ReleaseBuffer(len); strLine.Format(_T("line %d: "%s" "), i, strText); AFXDUMP(strLine);}
2023-06-29 08:16:551

如何把string字符串转成字段

你说的额是字符数组,是调用toArray方法
2023-06-29 08:17:022

c++查找文件路径

我一看就知道你是想写开机启动 写到注册表里面 哈哈 看看 这段代码 CString CClientApp::ReturnPath() { CString sPath; GetModuleFileName(NULL,sPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH); sPath.ReleaseBuffer (); int nPos; nPos=sPath.ReverseFind("\"); sPath=sPath.Left(nPos); return sPath; }
2023-06-29 08:17:091

C/C++ 中cstring用法?

常用的字符串类中没有 cstring 或者 Cstring注意拼写CString 是 MFC 或 ATL 中的字符串类操作符 + 对于字符串类来说就是字符串的拼接数值上累计的话,应该用 int 来保存保存输入字符的话,代码中的过程是对的
2023-06-29 08:17:172

CFile在C++中是怎么用的,是什么意思?

CFile 是 MFC 中的文件操作类是对 win32 API 中文件操作函数的封装
2023-06-29 08:17:262

c++调用jar包

不太懂,我直接复制的,一个C++调用JAR包的实例,希望能帮到你,版权归原作者一个简单需求:用C++调用Jar包。实现基本思路:调用CreateProcess API来启动cmd.exe运行jar包。调用类CJarAppCall。JarAppCall.h[cpp] view plain copy 在CODE上查看代码片派生到我的代码片#pragma once class CJarAppCall { public: CJarAppCall(void); ~CJarAppCall(void); /* @brief 执行Jar包调用,等待执行完成返回 @param[in] strJarDir jar包目录 @param[in] strJarName jar包名称 @return 执行是否成功 */ bool Run(const CString& strJarDir, const CString& strJarName); private: bool CallApp(const CString& strJarName); }; JarAppCall.cpp[cpp] view plain copy 在CODE上查看代码片派生到我的代码片#include "StdAfx.h" #include "JarAppCall.h" CJarAppCall::CJarAppCall(void) { } CJarAppCall::~CJarAppCall(void) { } bool CJarAppCall::Run(const CString& strJarDir, const CString& strJarName) { //缓存当前目录 WCHAR sOldDir[MAX_PATH] = {0}; GetCurrentDirectory(MAX_PATH, sOldDir); //设置当前目录为jar包目录 SetCurrentDirectory(strJarDir); bool bCalRest = CallApp(strJarName); //还原当前目录 SetCurrentDirectory(sOldDir); return bCalRest; } bool CJarAppCall::CallApp(const CString& strJarName) { WCHAR sSysDir[MAX_PATH] = {0}; GetSystemDirectory(sSysDir, MAX_PATH); CString strFullPath = sSysDir; strFullPath += _T("\cmd.exe"); CString strCmdLine = _T(" /C "); strCmdLine += _T("java -jar "); strCmdLine += strJarName; STARTUPINFO si = {sizeof(si)}; PROCESS_INFORMATION pi; BOOL bRunProgram = CreateProcess(strFullPath.GetBuffer(), strCmdLine.GetBuffer(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); strFullPath.ReleaseBuffer(); strCmdLine.ReleaseBuffer(); if (!bRunProgram) { return false; } // 等待程序结束 WaitForSingleObject(pi.hProcess,INFINITE); CloseHandle(pi.hProcess); return true; } 调用示例[cpp] view plain copy 在CODE上查看代码片派生到我的代码片{ CString strJarDir = _T("F:\JarRunTest"); CString strJarName = _T("run.jar"); CJarAppCall jarCall; if (!jarCall.Run(strJarDir, strJarName)) { //启动失败 AfxMessageBox(_T("启动失败")); return; } AfxMessageBox(_T("调用完成")); }
2023-06-29 08:17:331

MFC 中char转CString问题

GetWindowText的参数可以是CString 类型的,为什么要使用字符数组做参数,之后再把字符数组转换为CString 类型的?没有这个必要吧朋友。
2023-06-29 08:17:414

VC 怎样获得执行文件所在路径

同奶茶dsk的
2023-06-29 08:18:015

请问:在VB6.0中使用winsock控件,作为服务器要设置本地IP地址吗?

服务端可以这样:With Listen.Close.LocalPort = Text1.Text " (根据Text1中的数值来定监听端口 ( 假如为:4567 ) ).ListenEnd With客户端可以这样:Winsock1.CloseWinsock1.Connect Text1.Text, Text2.Text "(Text1为要连接的服务器IP地址(服务端在本地可以为 127.0.0.1), Text2为服务端监听的端口 ( 4567 ) )
2023-06-29 08:18:221

wm_copydata使用方法

#pragma pack(1) struct Student { char ID[10]; TCHAR Name[20]; UINT Age; UINT Grade; char Room[5]; char Tel[12]; }; #pragma pack() //********************************************************** 因为需要在接收方的OnCopyData()函数中区分发送的两种不同类型数据。所以就定义了以下两个常量: #define STRING 1 #define STUDENT 2 发送方: void CSendDataDlg::OnBtSend() //实现CString类型数据的发送 { UpdateData(TRUE); if (m_szData.IsEmpty()) { m_szData = _T("Hello"); UpdateData(FALSE); } // m_szData += ""; HWND hWndRcv = ::FindWindow(NULL,"Receiver"); if (hWndRcv == NULL) { AfxMessageBox(_T("找不到接收窗口,发送不成功")); return ; } COPYDATASTRUCT cpd; cpd.dwData = STRING; //标志为CString类型 cpd.cbData = m_szData.GetLength() + 1; //GetLength()只是取得实际字符的长度,没有包括"". cpd.lpData = (void*)m_szData.GetBuffer(cpd.cbData); ::SendMessage(hWndRcv,WM_COPYDATA,(WPARAM)this->m_hWnd,(LPARAM)&cpd); m_szData.ReleaseBuffer(); AfxMessageBox(_T("发送成功")); } void CSendDataDlg::OnBtStu() //实现Student类型数据的发送 { UpdateData(); m_szID += ""; m_szName += ""; m_szRoom += ""; m_szTel += ""; m_pStu = new Student(); strcpy(m_pStu->ID,m_szID.GetBuffer(m_szID.GetLength())); _tcscpy(m_pStu->Name,m_szName.GetBuffer(m_szName.GetLength())); strcpy(m_pStu->Room,m_szRoom.GetBuffer(m_szRoom.GetLength())); strcpy(m_pStu->Tel,m_szTel.GetBuffer(m_szTel.GetLength())); m_szID.ReleaseBuffer();m_szName.ReleaseBuffer(); m_szRoom.ReleaseBuffer();m_szTel.ReleaseBuffer(); m_pStu->Age = m_nAge; m_pStu->Grade = m_nGrade; HWND hWndRcv = ::FindWindow(NULL,"Receiver"); if (hWndRcv == NULL) { AfxMessageBox(_T("找不到接收窗口,发送不成功")); return ; } COPYDATASTRUCT cpd; cpd.dwData = STUDENT; // 标志为Student类型 cpd.cbData = sizeof(Student); cpd.lpData = (PVOID)m_pStu; ::SendMessage(hWndRcv,WM_COPYDATA,(WPARAM)this->m_hWnd,(LPARAM)&cpd); delete m_pStu; AfxMessageBox(_T("发送成功")); } 接收方: 在OnInitDialog方法中: //*************************************************************** //初始化ListCtrl控件 LVCOLUMN column; column.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; column.cx = 80; column.iSubItem = 0; column.pszText = _T("ID"); m_ListCtl.InsertColumn(0,&column); column.cx = 80; column.pszText = _T("Name"); column.iSubItem = 1; m_ListCtl.InsertColumn(1,&column); column.cx = 55; column.pszText = _T("Age"); column.iSubItem = 2; m_ListCtl.InsertColumn(2,&column); column.cx = 55; column.pszText = _T("Grade"); column.iSubItem = 3; m_ListCtl.InsertColumn(3,&column); column.cx = 55; column.pszText = _T("Room"); column.iSubItem = 4; m_ListCtl.InsertColumn(4,&column); column.cx = 80; column.pszText = _T("Tel"); column.iSubItem = 5; m_ListCtl.InsertColumn(5,&column); BOOL CReceiverDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { switch (pCopyDataStruct->dwData) { // 接收到的是CString类型 case STRING: m_szData += (LPCSTR)(pCopyDataStruct->lpData); UpdateData(FALSE); break; case STUDENT: // 接收到的是Student类型 CString id,name,room,tel; UINT age,grade; CString str; Student* pStu = (Student*)(pCopyDataStruct->lpData); id = pStu->ID; name = pStu->Name; room = pStu->Room; tel = pStu->Tel; age = pStu->Age; grade = pStu->Grade; LVITEM item; // 把接收到的数据显示到ListCtrl控件上 item.mask = LVIF_TEXT; int n = m_ListCtl.GetItemCount(); item.iItem = n; item.iSubItem = 0; item.pszText = id.GetBuffer(id.GetLength()); id.ReleaseBuffer(); m_ListCtl.InsertItem(&item); m_ListCtl.SetItemText(n,1,name); str.Format("%d",age); m_ListCtl.SetItemText(n,2,str); str.Format("%d",grade); m_ListCtl.SetItemText(n,3,str); m_ListCtl.SetItemText(n,4,room); m_ListCtl.SetItemText(n,5,tel); UpdateData(FALSE); //delete pStu; break; } // return CDialog::OnCopyData(pWnd, pCopyDataStruct); return TRUE; } 参考资料: http://www.programbbs.com/doc/304.htm
2023-06-29 08:18:301

mfc如何彻底退出进程

这应该不可能,因为你的进程退出了,分配给你进程的内存一定会释放掉。包括你出错被迫强行退出也是一样。你的内存泄露恐怕和你的代码本身质量问题有关系,和exitProcess没关系。---------------------------------------------------------------------------------------------------哈哈哈,管理员不懂在瞎选?可怜的楼主看看这篇文章 http://blog.csdn.net/yangywyangyw/article/details/6132341 只要你的程序退出了,不管你那令人作呕的垃圾代码有多少内存泄露也不管你是如何退出的,操作系统都会回收干净的,如果操作系统不能保证这一点,那操作系统一天要死多少次机才算合格???这都不懂还写什么VC程序!还笑话管理员瞎选呢,哈哈哈,搞笑。
2023-06-29 08:18:383

跪求Visual C++程序连接数据库的方法,十分火急!!!

2023-06-29 08:18:471

VC如何保存复选框的bool型变量值到ini配置文件中?

bool就当int保存啊CString GetExePath(){ CString strPathName; GetModuleFileName(NULL,strPathName.GetBuffer(256),256); strPathName.ReleaseBuffer(256); int nPos = strPathName.ReverseFind("\"); strPathName = strPathName.Left(nPos + 1); return strPathName;}CString GetConSetting(CString strAppName, CString strKeyName,CString strDefault){ const int SIZE = 1000 ; char szReturn[SIZE] = {0} ; CString strConFileName = GetExePath() + "con1.ini"; GetPrivateProfileString(strAppName,strKeyName,strDefault,szReturn,SIZE,(LPCTSTR)strConFileName); return szReturn ;}int GetConSetting(CString strAppName, CString strKeyName,int iDefault){ CString strDefault; strDefault.Format("%d",iDefault); CString strReturn = GetConSetting(strAppName,strKeyName,strDefault); int iReturn ; sscanf((LPCTSTR)strReturn,"%d",&iReturn); return iReturn ;}void SetConSetting(CString strAppName, CString strKeyName,CString strValue){ CString strConFileName = GetExePath() + "con1.ini"; WritePrivateProfileString(strAppName,strKeyName,strValue,strConFileName); }void SetConSetting(CString strAppName, CString strKeyName,int iValue){ CString strValue ; strValue.Format("%d",iValue); SetConSetting(strAppName,strKeyName,strValue); }
2023-06-29 08:18:542

MFC CFileFind和CFile遍历一个指定文件夹并删除里面的所有文件(里面没有下层文件夹目录)问题

首先,不要用TCHAR,其次,你的for循环有问题,再者Remove函数只可删除文件,不可删除目录,而且你还没加异常判断。void RemoveFileInDir(const char* dir) //比如 E:\Test{ char buff[256]; sprintf_s(buff,"%s\*.*",dir);CString name,path; CFileFind find; BOOL bFind = find.FindFile(buff); try{ while(bFind) { bFind = find.FindNextFile();name = find.GetFileName(); if(find.IsDirectory() || name.Compare(".") == 0 || name.Compare("..") == 0) continue;path = find.GetFilePath(); CFile::Remove(path); cout<<path.LPCTSTR();<<endl; } }catch(CFileException &e){ e.GetErrorMessage(buff,256); cout<<buff<<endl; }}
2023-06-29 08:19:023

(C++) CString转string 怎么转!!用GetBuffer()不行的!!!

string()
2023-06-29 08:19:275

VC++ 中WM_COPYDATA 怎么样应用来实现两个进程间的数据传输 举个简单例子吧

#pragma pack(1) struct Student { char ID[10]; TCHAR Name[20]; UINT Age; UINT Grade; char Room[5]; char Tel[12]; }; #pragma pack() //********************************************************** 因为需要在接收方的OnCopyData()函数中区分发送的两种不同类型数据。所以就定义了以下两个常量:#define STRING 1 #define STUDENT 2 发送方:void CSendDataDlg::OnBtSend() //实现CString类型数据的发送 { UpdateData(TRUE); if (m_szData.IsEmpty()) { m_szData = _T("Hello"); UpdateData(FALSE); } // m_szData += ""; HWND hWndRcv = ::FindWindow(NULL,"Receiver"); if (hWndRcv == NULL) { AfxMessageBox(_T("找不到接收窗口,发送不成功")); return ; }COPYDATASTRUCT cpd; cpd.dwData = STRING; //标志为CString类型 cpd.cbData = m_szData.GetLength() + 1; //GetLength()只是取得实际字符的长度,没有包括"".cpd.lpData = (void*)m_szData.GetBuffer(cpd.cbData);::SendMessage(hWndRcv,WM_COPYDATA,(WPARAM)this->m_hWnd,(LPARAM)&cpd); m_szData.ReleaseBuffer();AfxMessageBox(_T("发送成功")); }void CSendDataDlg::OnBtStu() //实现Student类型数据的发送 { UpdateData(); m_szID += ""; m_szName += ""; m_szRoom += ""; m_szTel += "";m_pStu = new Student();strcpy(m_pStu->ID,m_szID.GetBuffer(m_szID.GetLength())); _tcscpy(m_pStu->Name,m_szName.GetBuffer(m_szName.GetLength())); strcpy(m_pStu->Room,m_szRoom.GetBuffer(m_szRoom.GetLength())); strcpy(m_pStu->Tel,m_szTel.GetBuffer(m_szTel.GetLength()));m_szID.ReleaseBuffer();m_szName.ReleaseBuffer(); m_szRoom.ReleaseBuffer();m_szTel.ReleaseBuffer();m_pStu->Age = m_nAge; m_pStu->Grade = m_nGrade;HWND hWndRcv = ::FindWindow(NULL,"Receiver"); if (hWndRcv == NULL) { AfxMessageBox(_T("找不到接收窗口,发送不成功")); return ; } COPYDATASTRUCT cpd; cpd.dwData = STUDENT; // 标志为Student类型 cpd.cbData = sizeof(Student);cpd.lpData = (PVOID)m_pStu;::SendMessage(hWndRcv,WM_COPYDATA,(WPARAM)this->m_hWnd,(LPARAM)&cpd); delete m_pStu; AfxMessageBox(_T("发送成功")); }接收方:在OnInitDialog方法中://*************************************************************** //初始化ListCtrl控件 LVCOLUMN column; column.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;column.cx = 80; column.iSubItem = 0; column.pszText = _T("ID"); m_ListCtl.InsertColumn(0,&column);column.cx = 80; column.pszText = _T("Name"); column.iSubItem = 1; m_ListCtl.InsertColumn(1,&column);column.cx = 55; column.pszText = _T("Age"); column.iSubItem = 2; m_ListCtl.InsertColumn(2,&column);column.cx = 55; column.pszText = _T("Grade"); column.iSubItem = 3; m_ListCtl.InsertColumn(3,&column);column.cx = 55; column.pszText = _T("Room"); column.iSubItem = 4; m_ListCtl.InsertColumn(4,&column);column.cx = 80; column.pszText = _T("Tel"); column.iSubItem = 5; m_ListCtl.InsertColumn(5,&column); BOOL CReceiverDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { switch (pCopyDataStruct->dwData) { // 接收到的是CString类型 case STRING: m_szData += (LPCSTR)(pCopyDataStruct->lpData); UpdateData(FALSE); break; case STUDENT: // 接收到的是Student类型CString id,name,room,tel; UINT age,grade; CString str; Student* pStu = (Student*)(pCopyDataStruct->lpData);id = pStu->ID; name = pStu->Name; room = pStu->Room; tel = pStu->Tel; age = pStu->Age; grade = pStu->Grade;LVITEM item; // 把接收到的数据显示到ListCtrl控件上item.mask = LVIF_TEXT; int n = m_ListCtl.GetItemCount();item.iItem = n; item.iSubItem = 0; item.pszText = id.GetBuffer(id.GetLength()); id.ReleaseBuffer(); m_ListCtl.InsertItem(&item);m_ListCtl.SetItemText(n,1,name);str.Format("%d",age); m_ListCtl.SetItemText(n,2,str);str.Format("%d",grade); m_ListCtl.SetItemText(n,3,str);m_ListCtl.SetItemText(n,4,room); m_ListCtl.SetItemText(n,5,tel); UpdateData(FALSE); //delete pStu; break; }// return CDialog::OnCopyData(pWnd, pCopyDataStruct); return TRUE; }
2023-06-29 08:19:531

CString::GetBuffer()的原理(答了就得分!)

首先你没理解GetBuffer(int nMinBuflength)这个函数,首先他的参数是至少要输入的字符个数。其次他的返回值是个指向CSring类的指针。为何你要输入一个指针?给你个MSDN的例子吧!CString str;char* pc = str.GetBuffer(256); // need at least 256 bytes of spacefor (int i=1; i<256; i++)pc[i] = (char)i;pc[256]=0;str.ReleaseBuffer(); _____________________________看来得再给你说下首先看下msdn的注释:Returns a pointer to the internal character buffer for the CString object. The returned LPTSTR is not const and thus allows direct modification of CString contents.返回个指向自身的指针,也即是说对pc的修改就是对str的修改。还有你说的属于有问题,他们都是指向同一个内存的指针。
2023-06-29 08:20:001

c语言函数解 答输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数 求下面解答!!1

助人为快乐之本
2023-06-29 08:20:115

BlastBufferQueue 原理解读

Google针对新的同步机制,在BBQ对象JAVA层面设计了一系列功能接口,列举功能更新较大几个接口: 提供用于下一次缓冲区要更新的事务。 BBQ 不会立即提交此事务,通过该接口将下一帧的提交控制在调用者手中,调用者可以将其用于更高级别的同步。 将传入的事务合并到 BBQ 中的下一个事务。 当具有指定帧号的下一帧可用时,将直接与含有Buffer的事务进行合并并提交。 客户端可以监听Buffer的合成状态,在 SurfaceFlinger 中已应用包含带有 framenumber 的缓冲区的事务时触发回调,通知客户端合成完成。 与之前Android版本不同的是,Surface对象的创建、Buffer size与Surface size的更新也支持直接通过BBQ进行操作。 Android 12 Google将BufferQueue(简称BQ)组件从SF端移动到了客户端,BQ组件的初始化也放在BBQ的初始化中。通过类名可以看出BBQ更像是BQ的装饰者,在BQ本来功能特性的基础上添加了同步的功能。 通过官图大概了解,整个生产消费模型都在客户端,图形缓冲区的出队、入队、获取等操作都在客户端完成,预示着生产着模型从远程通讯变成了本地通讯, 消费者监听器也从SF端的 ContentsChangedListener 。带来的改变就是客户端需要通过事务Transaction来向SF端提交Buffer与图层的属性。 接下来以应用显示流程为例,梳理下BBQ的初始化流程: 应用端通过方法 relayoutWindow 向WMS服务申请窗口布局,创建应用对应SurfaceControl,随后根据SurfaceControl创建BlastBufferQueue: frameworks / base / core / java / android / view / ViewRootImpl.java BBQ主要核心逻辑的初始化都放在了Native对象的构造函数,做了以下几件事: frameworks / native / libs / gui / BLASTBufferQueue.cpp frameworks / native / libs / gui / BLASTBufferQueue.cpp BLASTBufferItemConsumer (简称BBIC)继承自 ConsumerBase ,创建BBIC的同时,消费者模型与消费者监听器建立起了连接: frameworks / native / libs / gui / ConsumerBase.cpp frameworks / native / libs / gui / BufferQueueConsumer.cpp 这一步也就让 BBIC 建立了对Buffer状态的监听。接下来看BBQ如何有选择性的监听Buffer的状态。 BBIC 拥有监听Buffer所有状态的能力,BBQ对Buffer特定状态的监听离不开 BBIC,因此,BBQ 继承了两个抽象类 ConsumerBase 与 BufferItemConsumer ,分别针对 Buffer 消费状态与生产状态进行监听。 frameworks / native / libs / gui / BufferQueueConsumer.cpp BBQ初始化完成,消费者模型建立完成,由于BBQ动态监听缓冲区的状态,如果有可消费的缓冲区,BBQ会触发缓冲区的事务提交: 通过梳理BBQ的初始化,对消费者端的大概流程有了一定的认识,接下来梳理下生产者方的代表,也就是Surface。Android 显示的的内容来源于各种绘制模块,而这些绘制模块需要与BQ建立连接,获取Buffer用以绘制,这样才能将绘制的画像通过BBQ提交给SF合成。Surface作为生产者模型与绘制模块之间桥梁,相关的流程掌握显得尤为重要。 绘制模块指的是那些图像生产者,如以使用SurfaceView、GlSurfaceView、TextureView控件为代表的Video模块、Camera模块、游戏应用等,以及使用软件绘制、硬件加速绘制为代表的普通控件。 回到创建BBQ的流程,在ViewRootImpl.getOrCreateBLASTSurface方法中,创建完BBQ,紧接着会创建Surface对象,直接看Native 对象的构造函数: 首先Surface的创建会传入生产者模型 GraphicBufferProducer ,这样Surface对象拥有了操作缓冲区的能力,同时在构造函数中Surface提供了一系列hook为首的函数,连接到 ANativeWindow 的函数指针,为的是给EGL模块提供对缓冲区操作的入口。而hook函数会直接调用内部的本地函数,以 hook_queueBuffer 为例: 同时软件绘制不需要通过hook函数来中转,当上层通过Surface.lockCanvas方法获取画布时会直接调用本地函数函数 Surface::dequeueBuffer 。 Surface只是绘制的中介,还需要与绘制模块进行连接后,绘制模块才能获取缓冲区和绘制图像数据,关于绘制模块如何连接到Surface,这里不做记录。 结合第一节的关于BBQ 重点API功能介绍与BBQ的初始化流程,回过头看下这三个API功能是如何实现的。 首先看 setNextTransaction 函数,调用者通过该接口可以实现将当前帧 Buffer 的提交权利控制在自己手中,同时可以加入其他图层想要的更新,然后提交,放在同一帧生效。可以思考下,如果当前帧的控制权交给了调用者,是否会导致下一帧的紊乱呢?看下这块流程: 这里BBQ做了线程阻塞的机制,当绘制模块绘制完成下一帧,并将Buffer放回了缓冲区队列,触发BBQ的 onFrameAvailable 回调,如果调用者使用了 setNextTransaction 函数传入了自定义事务,那么就会在 onFrameAvailable 函数中阻塞住线程, 暂停执行下一帧的 processNextBufferLocked 。而唤醒线程的任务交给了 releaseBufferCallback 函数。 当前帧会执行绘制提交函数 processNextBufferLocked ,但是不会立即提交,会将事务控制在自己手中。可以看到, releaseBufferCallback 的回调函数会通过 t->setBuffer传递到SF端。 也就是说当调用者主动提交事务后,SF端合成完成后会回调该通知,唤醒线程。否则会一直阻塞等待调用者提交。 大概流程如图示: 根据BBQ相关文档提示: 该机制在同步单个帧时阻塞在 UI 线程中很好,但在尝试同步多个帧时效果不佳。 它最终会减慢渲染速度。 相反,在 RenderThread 级别处理同步以允许 UI 线程继续处理帧 因此多帧同步还是有优化空间。 将调用者传入的事务合并到 BBQ 中的下一个事务。 当具有指定帧号的下一帧可用时,将直接与含有Buffer的事务进行合并并提交。也就是说将调用者事务所包含的其他对图层属性的更新合入到BBQ的事务中,与BBQ的事务在指定帧数一同生效。这个怎么实现的呢? 这个函数会将调用者传入的事务都保存在 mPendingTransactions 集合中,当执行到下一帧的 processNextBufferLocked 函数时,将集合中的事务都合入到BBQ事务中,然后直接提交: 大概流程如图示: 客户端可以监听Buffer的合成状态,在 SurfaceFlinger 中已应用包含带有 frameNumber 的缓冲区的事务时触发回调,通知调用者合成完成。 通过 t->addTransactionCompletedCallback 将 transactionCallbackThunk 回调函数传给了SF,当合成完成会触发回调,并通知调用者状态。 根据上面流程的梳理,用一张图总结下BBQ与相关模块之间的结构关系:
2023-06-29 08:20:271

关于VC++中MSCOMM控件的SetSetting的参数设置问题

m_ctrlComm.SetSettings(",,atoi(strltem),");不合法。你这样其实设置的是",,atoi(strltem),"这个串。建议你参数值最后统一设置,而不要分开设置。改为:CString myset;myset.Format("%d,%s,%d,%d",atoi(strSpeed),strFlag,atoi(strBit),atoi(strStop));m_ctrlComm.SetSettings(myset); strFlag是校验标志(E、N或O)
2023-06-29 08:20:341

请教MFC高手:关于CArchive类的用法,在线等,急!!!

这个谁要会,可真是高手!
2023-06-29 08:21:212

MFC的Edit控件里,如何实现输入一组计算表达式:例如5*(3+3)-1,之后点击按钮后输出结果?

在消息响应里面写: system("calc");
2023-06-29 08:21:292

非阻塞套接字实现的文件传输程序

嗯,好像我们的课程设计也是类似这个留名关注下,说不定用得上^_^
2023-06-29 08:21:373

buffer里position函数是什么意思

GetBuffer和ReleaseBuffer是从其父类CSimpleStringT继承过来的。GetBuffer的作用是:“Returns a pointer to the internal character buffer”,ReleaseBuffer的作用是:“Releases control of the buffer allocated by GetBuffer.”。这两个函数的常见用法如下:CString str;const int bufferSize = 10;LPTSTR p = str.GetBuffer(bufferSize);_tcscpy_s(p, bufferSize, _T("abcd1234.")); // use the buffer directlystr.ReleaseBuffer(); // Surplus(多余的) memory released, p is now invalid.给GetBuffer函数传递的参数bufferSize,意思是:“The minimum size of the character buffer in characters. This value does not include space for a null terminator.”。对于调用ReleaseBuffer释放内存时,是否应该带参数,msdn是这样说的:“If you keep track of the string length yourself, you should not append the terminating null character. You must, however, specify the final string length when you release the buffer with ReleaseBuffer. If you do append a terminating null character, you should pass –1 (the default) for the length to ReleaseBuffer, and ReleaseBuffer will perform a strlen on the buffer to determine its length.”。因为ReleaseBuffer函数的默认参数是-1,所以通常在调用ReleaseBuffer函数时省去-1参数的书写。
2023-06-29 08:21:571

如何给Lpwstr赋值

LPWSTR ABC=_T("字符串");LPWSTR是Unicode字符,所以最好用_T("字符串")CString str(_T("abc"));LPWSTR pStr = str.GetBuffer();str.ReleaseBuffer;
2023-06-29 08:22:041

VC中如何将CString类型转换成unsigned char *类型?

CString str = "abcd";unsigned char* pC = (unsigned char*)(LPCTSTR)str;或CString s("ABC");unsigned char *puc = (unsigned char*)s.GetBuffer( s.GetLength() );...;//必须等指针使用完之后才能进行下一条释放命令。s.ReleaseBuffer();
2023-06-29 08:22:121

vc++中如何将 ‘CString’ 转换成 ‘ char * ’ 类型?

char* pc = a.GetBuffer(a.GetLength+1);
2023-06-29 08:22:192

releasebuffer函数是什么意思

GetBuffer和ReleaseBuffer是从其父类CSimpleStringT继承过来的。GetBuffer的作用是:“Returns a pointer to the internal character buffer”,ReleaseBuffer的作用是:“Releases control of the buffer allocated by GetBuffer.”。这两个函数的常见用法如下:CString str;const int bufferSize = 10;LPTSTR p = str.GetBuffer(bufferSize);_tcscpy_s(p, bufferSize, _T("abcd1234.")); // use the buffer directlystr.ReleaseBuffer(); // Surplus(多余的) memory released, p is now invalid.给GetBuffer函数传递的参数bufferSize,意思是:“The minimum size of the character buffer in characters. This value does not include space for a null terminator.”。对于调用ReleaseBuffer释放内存时,是否应该带参数,msdn是这样说的:“If you keep track of the string length yourself, you should not append the terminating null character. You must, however, specify the final string length when you release the buffer with ReleaseBuffer. If you do append a terminating null character, you should pass –1 (the default) for the length to ReleaseBuffer, and ReleaseBuffer will perform a strlen on the buffer to determine its length.”。因为ReleaseBuffer函数的默认参数是-1,所以通常在调用ReleaseBuffer函数时省去-1参数的书写。
2023-06-29 08:22:271

CString obj;obj.GetBuffer(0);//这句代码什么意思?

CString::GetBufferLPTSTRGetBuffer(intnMinBufLength);throw(CMemoryException);返回值:一个指向对象的(以空字符结尾的)字符缓冲区的LPTSTR指针。参数:nMinBufLength字符缓冲区的以字符数表示的最小容量。这个值不包括一个结尾的空字符的空间。说明:此成员函数返回一个指向CString对象的内部字符缓冲区的指针。返回的LPTSTR不是const,因此可以允许直接修改CString的内容。如果你使用由GetBuffer返回的指针来改变字符串的内容,你必须在使用其它的CString成员函数之前调用ReleaseBuffer函数。在调用ReleaseBuffer之后,由GetBuffer返回的地址也许就无效了,因为其它的CString操作可能会导致CString缓冲区被重新分配。如果你没有改变此CString的长度,则缓冲区不会被重新分配。当此CString对象被销毁时,其缓冲区内存将被自动释放。注意,如果你自己知道字符串的长度,则你不应该添加结尾的空字符。但是,当你用ReleaseBuffer来释放该缓冲区时,你必须指定最后的字符串长度。如果你添加了结尾的空字符,你应该给ReleaseBuffer的长度参数传递-1,ReleaseBuffer将对该缓冲区执行strlen来确定它的长度。示例:下面的例子说明了如何用CString::GetBuffer。//CString::GetBuffer例子CStrings("abcd");#ifdef_DEBUGafxDump<<"CStrings"<<s<<" ";#endifLPTSTRp=s.GetBuffer(10);strcpy(p,"Hello");//直接访问CString对象。s.ReleaseBuffer();#ifdef_DEBUGafxDump<<"CStrings"<<s<<" ";#endif
2023-06-29 08:22:351

getbuffer(10)这个函数什么意思啊

getbuffer是什么意思,我知道是返回一个byte之类的吧,但为什么这里是255,这个函数是把cstring变为字符指针.后面的255是表示长度最小为这么多。
2023-06-29 08:22:421

关于Getbuffer()

呵呵!我看不懂!不好意思!赏钱别浪费了!给我吧!
2023-06-29 08:22:503

GetBuffer(0)//从0开始吗?

CString的GetBuffer,本意是返回PXSTR,这样用户可以直接在字符缓存上操作,缓存的大小就是GetBuffer中的参数。用0作为参数,就是直接使用CString现有的缓存。但其实如果就是输出的话,可以 cout << str << endl; 就可以了
2023-06-29 08:22:582

MFC中关联变量的事情不太懂,不知道是怎么联系在一下的,求解释一下!

DVE UpdateData(TRUE) UpdateData(FALSE)
2023-06-29 08:23:084

如何用C++将数字“1”转换成字符“1”?

1、字符串数字之间的转换(1)string --> char *string str("OK");char * p = str.c_str();(2)char * -->stringchar *p = "OK";string str(p);(3)char * -->CString char *p ="OK";CString m_Str(p);//或者CString m_Str;m_Str.Format("%s",p);(4)CString --> char *CString str("OK");char * p = str.GetBuffer(0);...str.ReleaseBuffer();(5)string --> CString CString.Format("%s", string.c_str()); (6)CString --> stringstring s(CString.GetBuffer(0)); GetBuffer()后必然要ReleaseBuffer(),不然就没有开释缓冲区所占的空间,CString对象不克不及动态增长了。(7)double/float->CStringdouble data;CString.Format("%.2f",data); //保存2位小数(8)CString->doubleCString s="123.12";double d=atof(s); (9)string->doubledouble d=atof(s.c_str());2、数字转字符串:应用sprintf()函数char str[10];int a=1234321;sprintf(str,"%d",a);--------------------char str[10];double a=123.321;sprintf(str,"%.3lf",a);--------------------char str[10];int a=175;sprintf(str,"%x",a);//10进制转换成16进制,若是输出大写的字母是sprintf(str,"%X",a)--------------------char *itoa(int value, char* string, int radix); 同样也可以将数字转字符串,不过itoa()这个函数是平台相干的(不是标准里的),故在这里不推荐应用这个函数。3、字符串转数字:应用sscanf()函数char str[]="1234321";int a;sscanf(str,"%d",&a);.............char str[]="123.321";double a;sscanf(str,"%lf",&a);.............char str[]="AF";int a;sscanf(str,"%x",&a); //16进制转换成10进制别的也可以应用atoi(),atol(),atof().4、应用stringstream类用ostringstream对象写一个字符串,类似于sprintf() ostringstream s1;int i = 22;s1 << "Hello " << i << endl;string s2 = s1.str();cout << s2;用istringstream对象读一个字符串,类似于sscanf() istringstream stream1;string string1 = "25";stream1.str(string1);int i;stream1 >> i;cout << i << endl; // displays 25
2023-06-29 08:23:291

如何用C++将数字“1”转换成字符“1”

觉得 一楼的可以
2023-06-29 08:23:374

怎样在VC中实现将文件中的内容转入文本框中?

先让编辑框关联一个CString变量,然后读文件到该CString中,最后UpdateData(FALSE);
2023-06-29 08:23:442

VC++:char数组怎么转到LPCTSTR

个人觉得前面加个强制转换就可以了pFrame->MessageBoxW("Document not saved! Will you close it?",(LPCTSTR)title,MB_YESNO ) ;
2023-06-29 08:23:532

怎样获取 edit控件读取每行信息的字符个数

m_Edit.GetLine(0,lpszBuffer);//读取edit控件中第一行文本存入lpszBuffer指向的字符串中,m_Edit是与edit控件关联的变量可参考代码:int i, nLineCount = m_myEdit.GetLineCount();//m_myEdit是与edit控件关联的变量CString strText, strLine;// Dump every line of text of the edit control.for (i=0; i < nLineCount; i++){ // length of line i: int len = m_myEdit.LineLength(m_myEdit.LineIndex(i)); m_myEdit.GetLine(i, strText.GetBuffer(len), len); strText.ReleaseBuffer(len); strLine.Format(_T("line %d: "%s" "), i, strText); AFXDUMP(strLine);//输出得到的每行数据}
2023-06-29 08:24:001