复习C字符串处理

【编程拾遗】VC++中LPCTSTR、CString、char *、string之间的相互转换 字符集 在VC2012中,字符集默认采用Unicode字符集(Use Unicode Charecter Set选项),其值还可以设置为多字节字符集(Use Multi-Byte Charecter Set)。 为什么要使用Unicode 可以很容易地在不同语言之间进行数据交换。使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。提高应用程序的运行效率。 阅读详情
用惯了java,现在要开发个C程序还真不大习惯,尤其是字符串处理这块,看来知识要不断温故而知新才是。
VC数据转换~好东西~~
CString ,BSTR ,LPCTSTR之间关系和区别

CString是一个动态TCHAR数组,BSTR是一种专有格式的字符串(需要用系统提供的函数来操纵,LPCTSTR只是一个常量的TCHAR指针。

CString 是一个完全独立的类,动态的TCHAR数组,封装了 + 等操作符和字符串操作方法。
typedef OLECHAR FAR* BSTR;
typedef const char * LPCTSTR;

vc++中各种字符串的表示法

首先char* 是指向ANSI字符数组的指针,其中每个字符占据8位(有效数据是除掉最高位的其他7位),这里保持了与传统的C,C++的兼容。

LP的含义是长指针(long pointer)。LPSTR是一个指向以‘/0’结尾的ANSI字符数组的指针,与char*可以互换使用,在win32中较多地使用LPSTR。
而LPCSTR中增加的‘C’的含义是“CONSTANT”(常量),表明这种数据类型的实例不能被使用它的API函数改变,除此之外,它与LPSTR是等同的。
1.LP表示长指针,在win16下有长指针(LP)和短指针(P)的区别,而在win32下是没有区别的,都是32位.所以这里的LP和P是等价的.
2.C表示const
3.T是什么东西呢,我们知道TCHAR在采用Unicode方式编译时是wchar_t,在普通时编译成char.

为 了满足程序代码国际化的需要,业界推出了Unicode标准,它提供了一种简单和一致的表达字符串的方法,所有字符中的字节都是16位的值,其数量也可以 满足差不多世界上所有书面语言字符的编码需求,开发程序时使用Unicode(类型为wchar_t)是一种被鼓励的做法。

LPWSTR与LPCWSTR由此产生,它们的含义类似于LPSTR与LPCSTR,只是字符数据是16位的wchar_t而不是char。

然后为了实现两种编码的通用,提出了TCHAR的定义:
如果定义_UNICODE,声明如下:
typedef wchar_t TCHAR;
如果没有定义_UNICODE,则声明如下:
typedef char TCHAR;

LPTSTR和LPCTSTR中的含义就是每个字符是这样的TCHAR。

CString类中的字符就是被声明为TCHAR类型的,它提供了一个封装好的类供用户方便地使用。

LPCTSTR:
     #ifdef _UNICODE
        typedef const wchar_t * LPCTSTR;
     #else
        typedef const char * LPCTSTR;
     #endif

VC常用数据类型使用转换详解
 
先定义一些常见类型变量借以说明
int i = 100;
long l = 2001;
float f=300.2;
double d=12345.119;
char username[]="女侠程佩君";
char temp[200];
char *buf;
CString str;
_variant_t v1;
_bstr_t v2;

一、其它数据类型转换为字符串

短整型(int)
       itoa(i,temp,10);     //将i转换为字符串放入temp中,最后一个数字表示十进制
       itoa(i,temp,2);      //按二进制方式转换
长整型(long)
       ltoa(l,temp,10);


二、从其它包含字符串的变量中获取指向该字符串的指针

CString变量
str = "2008北京奥运";
buf = (LPSTR)(LPCTSTR)str;
BSTR类型的_variant_t变量
v1 = (_bstr_t)"程序员";
buf = _com_util::ConvertBSTRToString((_bstr_t)v1);

三、字符串转换为其它数据类型
strcpy(temp,"123");

短整型(int)
      i = atoi(temp);
长整型(long)
      l = atol(temp);
浮点(double)
      d = atof(temp);

四、其它数据类型转换到CString

使用CString的成员函数Format来转换,例如:

整数(int)
      str.Format("%d",i);
浮点数(float)
      str.Format("%f",i);
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
      str = username;

五、BSTR、_bstr_t与CComBSTR

CComBSTR、_bstr_t是对BSTR的封装,BSTR是指向字符串的32位指针。
char *转换到BSTR可以这样: BSTR b=_com_util::ConvertStringToBSTR("数据");     //使用前需要加上头文件comutil.h
反之可以使用char *p=_com_util::ConvertBSTRToString(b);


六、VARIANT 、_variant_t 与 COleVariant

VARIANT的结构可以参考头文件VC98/Include/OAIDL.H中关于结构体tagVARIANT的定义。
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:
VARIANT va;
int a=2001;
va.vt=VT_I4;    //指明整型数据
va.lVal=a;      //赋值

对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:

unsigned char bVal; VT_UI1
short iVal; VT_I2
long lVal;  VT_I4
float fltVal;  VT_R4
double dblVal;  VT_R8
VARIANT_BOOL boolVal;  VT_BOOL
SCODE scode;  VT_ERROR
CY cyVal;  VT_CY
DATE date;  VT_DATE
BSTR bstrVal;  VT_BSTR
IUnknown FAR* punkVal;  VT_UNKNOWN
IDispatch FAR* pdispVal;  VT_DISPATCH
SAFEARRAY FAR* parray;  VT_ARRAY|*
unsigned char FAR* pbVal;  VT_BYREF|VT_UI1
short FAR* piVal;  VT_BYREF|VT_I2
long FAR* plVal;  VT_BYREF|VT_I4
float FAR* pfltVal;  VT_BYREF|VT_R4
double FAR* pdblVal; VT_BYREF|VT_R8
VARIANT_BOOL FAR* pboolVal; VT_BYREF|VT_BOOL
SCODE FAR* pscode;  VT_BYREF|VT_ERROR
CY FAR* pcyVal;  VT_BYREF|VT_CY
DATE FAR* pdate; VT_BYREF|VT_DATE
BSTR FAR* pbstrVal;  VT_BYREF|VT_BSTR
IUnknown FAR* FAR* ppunkVal;  VT_BYREF|VT_UNKNOWN
IDispatch FAR* FAR* ppdispVal; VT_BYREF|VT_DISPATCH
SAFEARRAY FAR* FAR* pparray;  VT_ARRAY|*
VARIANT FAR* pvarVal;  VT_BYREF|VT_VARIANT
void FAR* byref;  VT_BYREF

_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
例如:
long l=222;
ing i=100;
_variant_t lVal(l);
lVal = (long)i;

COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
COleVariant v3 = "字符串", v4 = (long)1999;
CString str =(BSTR)v3.pbstrVal;
long i = v4.lVal;

七、其它

对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
LPARAM lParam;
WORD loValue = LOWORD(lParam);     //取低16位
WORD hiValue = HIWORD(lParam);     //取高16位
对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
WORD wValue;
BYTE loValue = LOBYTE(wValue);     //取低8位
BYTE hiValue = HIBYTE(wValue);     //取高8位

如何将CString类型的变量赋给char*类型的变量
1、GetBuffer函数:
使用CString::GetBuffer函数。
char *p;
CString str="hello";
p=str.GetBuffer(str.GetLength());
str.ReleaseBuffer();

将CString转换成char * 时
CString str("aaaaaaa");
strcpy(str.GetBuffer(10),"aa");
str.ReleaseBuffer();
当我们需要字符数组时调用GetBuffer(int n),其中n为我们需要的字符数组的长度.使用完成后一定要马上调用ReleaseBuffer();
还有很重要的一点就是,在能使用const char *的地方,就不要使用char *

2、memcpy:
CString mCS=_T("cxl");
char mch[20];
memcpy(mch,mCS,20);

3、用LPCTSTR强制转换: 尽量不使用
char *ch;
CString str;
ch=(LPSTR)(LPCTSTR)str;

CString str = "good";
char *tmp;
sprintf(tmp,"%s",(LPTSTR)(LPCTSTR)str);

4、
CString Msg;
Msg=Msg+"abc";
LPTSTR lpsz;
lpsz = new TCHAR[Msg.GetLength()+1];
_tcscpy(lpsz, Msg);
char * psz;
strcpy(psz,lpsz);


CString类向const char *转换
char a[100];
CString str("aaaaaa");
strncpy(a,(LPCTSTR)str,sizeof(a));
或者如下:
strncpy(a,str,sizeof(a));
以上两种用法都是正确地. 因为strncpy的第二个参数类型为const char *.所以编译器会自动将CString类转换成const char *.

CString转LPCTSTR (const char *)
CString cStr;
const char *lpctStr=(LPCTSTR)cStr;

LPCTSTR转CString
LPCTSTR lpctStr;
CString cStr=lpctStr;

将char*类型的变量赋给CString型的变量
可以直接赋值,如:
CString myString = "This is a test";
也可以利用构造函数,如:
CString s1("Tom");

将CString类型的变量赋给char []类型(字符串)的变量
1、sprintf()函数
CString str = "good";
char tmp[200] ;
sprintf(tmp, "%s",(LPCSTR)str); 
(LPCSTR)str这种强制转换相当于(LPTSTR)(LPCTSTR)str
CString类的变量需要转换为(char*)的时,使用(LPTSTR)(LPCTSTR)str

然而,LPCTSTR是const char *,也就是说,得到的字符串是不可写的!将其强制转换成LPTSTR去掉const,是极为危险的!
一不留神就会完蛋!要得到char *,应该用GetBuffer()或GetBufferSetLength(),用完后再调用ReleaseBuffer()。

2、strcpy()函数
CString str;
char c[256];
strcpy(c, str);

char mychar[1024];
CString source="Hello";
strcpy((char*)&mychar,(LPCTSTR)source);


关于CString的使用
1、指定 CString 形参
    对于大多数需要字符串参数的函数,最好将函数原型中的形参指定为一个指向字符 (LPCTSTR) 而非 CString 的 const 指针。
当将形参指定为指向字符的 const 指针时,可将指针传递到 TCHAR 数组(如字符串 ["hi there"])或传递到 CString 对象。
CString 对象将自动转换成 LPCTSTR。任何能够使用 LPCTSTR 的地方也能够使用 CString 对象。

2、如果某个形参将不会被修改,则也将该参数指定为常数字符串引用(即 const CString&)。如果函数要修改该字符串,
则删除 const 修饰符。如果需要默认为空值,则将其初始化为空字符串 [""],如下所示:
void AddCustomer( const CString& name, const CString& address, const CString& comment = "" );

3、对于大多数函数结果,按值返回 CString 对象即可。


串的基本运算
    对于串的基本运算,很多高级语言均提供了相应的运算符或标准的库函数来实现。
为叙述方便,先定义几个相关的变量:
    char s1[20]="dir/bin/appl",s2[20]="file.asm",s3[30],*p;
    int result;
    下面以C语言中串运算介绍串的基本运算
1、求串长
        int strlen(char *s);         //求串s的长度
    【例】printf("%d",strlen(s1));    //输出s1的串长12

2、串复制
    char *strcpy(char *to,*from);//将from串复制到to串中,并返回to开始处指针
    【例】strcpy(s3,s1);  //s3="dir/bin/appl",s1串不变


3、联接
    char *strcat(char *to,char *from);//将from串复制到to串的末尾,
                                      //并返回to串开始处的指针
    【例】strcat(s3,"/");    //s3="dir/bin/appl/"
         strcat(s3,s2);     //s3="dir/bin/appl/file.asm"

4、串比较
    int strcmp(char *s1,char *s2);//比较s1和s2的大小,
     //当s1<s2、s1>s2和s1=s2时,分别返回小于0、大于0和等于0的值
    【例】result=strcmp("baker","Baker");    //result>0
            result=strcmp("12","12");       //result=0
            result=strcmp("Joe","joseph")   //result<0

5、字符定位
    char *strchr(char *s,char c);//找c在字符串s中第一次出现的位置,
                                 //若找到,则返回该位置,否则返回NULL
    【例】p=strchr(s2,'.');      //p指向"file"之后的位置
     if(p) strcpy(p,".cpp");     //s2="file.cpp"

  注意:
     ①上述操作是最基本的,其中后 4个操作还有变种形式:strncpy,strncath和strnchr。
     ②其它的串操作见C的<string.h>。在不同的高级语言中,对串运算的种类及符号都不尽相同
     ③其余的串操作一般可由这些基本操作组合而成

    【例】求子串的操作可如下实现:
    void substr(char *sub,char *s,int pos,int len){
         //s和sub是字符数组,用sub返回串s的第pos个字符起长度为len的子串
         //其中0<=pos<=strlen(s)-1,且数组sub至少可容纳len+1个字符。
        if (pos<0||pos>strlen(s)-1||len<0)
            Error("parameter error!");
        strncpy(sub,&s[pos],len);      //从s[pos]起复制至多len个字符到sub

 
C语言复习(下) 上篇讲到堆内存,这篇继续剩下的内容 阅读详情

相关推荐

【Codesys】-扫描添加失败,手动添加第三方模块,真·DC模式的高速计数模块

欧姆龙耦合器(NX-ECC201)和高速计数模块(NX-EC0132)单独使用。扫描设备添加到Codesys中,会报错,无法自动添加。记录一下,以防忘记。高速的计数保证了位置的准确性,位置准确就能保证裁切的精度,一切的基础就在这儿了,奈何目前只有欧姆龙和倍福能做到这样的波形。

qq_35316470的博客 1339

CString 和 LPCTSTR等之间的转换

CString 和 LPCTSTR 可以说通用。 原因在于CString定义的自动类型转换,没什么奇特的,最简单的C++操作符重载而已。 常量字符串ansi和unicode的区分是由宏_T来决定的。但是用_T( "abcd ")时, 字符串 "abcd "就会根据编译时的是否定一_UNICODE来决定是char* 还是 w_char*。 同样,TCHAR 也是相同目的字符宏。 看看定义就明白了。简单起见,下面只介绍 ansi 的情况,unico...

大西瓜不甜的博客 4255

计算机科学类专升本复习之“C语言字符串处理函数”详解(初稿)

这边给大家介绍几个常用的字符串函数 1. 字符串连接函数 strcat() 格式: strcat(arrayName1,arrayName2);//arrayName1、arrayName2 为需要拼接的字符串。 strcat()函数把arrayName2 "连接" 到arrayName1后面,并删除原来arrayName1最后的标注'\0'。 这意味着,arrayName1必须足够的长,长到可以同时容纳arrayName1和arrayName2,否者会越界。 strcat(..

阿泉的博客 480

VC中数据类型之间的转换

CString ,BSTR ,LPCTSTR之间关系和区别CString是一个动态TCHAR数组,BSTR是一种专有格式的字符串(需要用系统提供的函数来操纵,LPCTSTR只是一个常量的TCHAR指针。CString 是一个完全独立的类,动态的TCHAR数组,封装了 + 等操作符和字符串操作方法。typedef OLECHAR FAR* BSTR;typedef const char * LPCT

ct_hero0902的专栏 1452

LPCTSTR和CString的关系

类型理解   LPCTSTR类型:   L表示long指针 这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32位操作系统中, long指针和near指针及far修饰符都是为了兼容的作用。没有实际意义。   P表示这是一个指针   C表示是一个常量   T表示在Win32环境中, 有一个_T宏   STR表示这个变量是一个字符...

weixin_34268843的博客 1107

CString 转换为LPWSTR

(LPWSTR)(LPCWSTR)(cmdLine.c_str()) //1、通过MultiByteToWideChar函数转换 MultiByteToWideChar函数是将多字节转换为宽字节的一个API函数,它的原型如下: int MultiByteToWideChar( UINT CodePage, // code page DWORD dwFlags, // chara...

Ryan 4577

C语言复习(上) 数组,函数,字符串处理

C语言复习(上) 数组,函数,字符串处理 1.序言 这是笔者的第一篇博客,笔者也刚刚结束了大一上学期的c语言期末考试,下面是我从开学到现在梳理的c语言常见算法和一些我觉得易错的点,如有错误麻烦指正,谢谢! 2.常见算法(其中一些算法笔者自己的理解写在了3.中,遇到理解不了的地方可以先去看看易错点整理) (1)编写函数求二次方程的根 void rootx(double a, double b, do...

weixin_45807786的博客 543

C语言字符串处理函数复习

#include <stdio.h> #include <string.h> int main() { char a[20], b[20], c[20]; strcpy(a,"programmer"); strcpy(b,a); strcpy(c,"C"); printf("a:%s\nb:%s\nc:%s\n", a, b, c); strcat(c,a); printf("%s\n%s\n", c, a); printf("%d %d %d\n", str.

Legendthree的博客 80

C语言复习笔记(常用字符串处理函数)

使用时需要加上预处理命令 #include <string.h> 字符串连接函数strcat 使用方法 strcat(str1,str2) 功能: 连接两个字符数组,返回值是字符数组1的首地址。 //strcat函数 #include<stdio.h> #include<string.h> //strcat int main() { char str1[10] = "hello"; char str2[10]; printf("please input stri

realttr的博客 720

C语言程序设计.复习7<字符串处理函数>

字符串处理函数 strlen(字符串); 用于计算字符串的长度 strcpy(目的字符数组,源字符串); 将一个字符串赋值到另外一个字符数组中 strcat(目的字符数组,源字符串);将一个字符串添加到一个字符数组的末尾 strcmp(字符串1,字符串2); 用于两个字符串的比较 以上四个函数原型都放在 #include<string.h> (编译预处理指令) 这个头文件中 计算字符串长度函数 char str[10] = {"China"}; printf("%d", st

weixin_62457071的博客 974

学过python对学c有帮助吗,学了python还要学c么

后来再搜google这个函数的原型,这个fgets函数会读入换行符号"\n".最后找到一段代码,老外实现的。代码很简单,但就是不出要的结果。语言都是相通的,学好一门语言,再学第二门语言就很简单,记录一下我复习c语言的过程。这个书上的代码基本都是c语言实现的,c语言很久没有用了,复习一下c语言。为了将本人的python培训提高一个层次,本人最近买了很多算法的书.怎么去掉后面的换行符。

wangyanqin0227的博客 676

嵌入式开发—C语言函数复习总结

​​- 无终止符检查​​:与 strcpy 不同,memcpy 严格按 n 字节拷贝,不因 \0 停止。​​不处理重叠内存​​:若 src 和 dest 内存重叠,行为未定义,应改用 memmove。,用于将字符串按指定的分隔符拆分成多个子字符串(称为 ​​token​​)。,其名称源自 ​​ASCII to floating point​​ 的缩写。,用于​​按字典顺序比较两个字符串的前 n 个字符​​。​​4. 与 strcmp 的区别​​。​​1. 函数原型(C/C++)​​。

sinat_30491515的博客 1215

c语言stand(time(0)),C语言复习0_准备工作

前言:第一次接触C语言是大一下学期的时候,2013年上半年,那个时候的开发工具还是VS C++,今天了解了一下,常用的开发工具变成了CodeBlocks。决定趁着毕业到入职这一段CD时间,拾起这门语言,为将来的工作做准备(只学一门Python确实不行),多学点总是不会错的。准备:CodeBlocks下载并安装正文C和Python这种动态语言不一样,需要先编译后执行,编译完如果是0 errors,0...

weixin_34221197的博客 915

C语言——字符串指针篇

参考了网上很多博客的文章(主要参考:C语言中文网),自己屡屡思路有错请指出。 概念 字符数组   在C语言中没有专门的字符串变量(string类型),故一般是通过数组的方法来实现,被称为字符数组(存放字符的数组,实际上一系列字符集合(字符串)),如: char str[]="hello world!" /这种写法最简洁,当然也可写成char str[20]={"hello world!"}   要注意:字符数组 只有在定义时才可一次性赋值,一旦定义完就只能一个个赋值 ,如: char str[4]; s

weixin_42645653的博客 2万+

C复习-标准函数库:数值计算+字符串转换+日期+信号处理+locale

C复习:标准库函数

陆沙的博客 701

《C Primer Plus》第11章复习题与编程练习

《C Primer Plus》第11章复习题与编程练习

ProgramNovice的博客 1626

C语言复习合集【9】字符数组和字符串:字符数组、字符串数组、字符串函数(strlen、strcpy、strcat、strcmp、字符串拓展用法)

字符数组和字符串:字符数组、字符串数组、字符串函数(strlen、strcpy、strcat、strcmp、字符串拓展用法)大家可以通过代码理解学习,帮助大家C语言期末复习。一、

2301_80013104的博客 2083

C语言字符串处理函数

函数名: strcpy 功 能: 拷贝一个字符串到另一个 用 法: char *stpcpy(char *destin, char *source); 程序例: #include &lt;stdi

linjcai的博客 205

uniapp [安卓苹果App端] - 解决支付宝支付报错requestPayment:fail [payment支付宝:62009]未知错误,使用uni.requestPayment支付报错排查方案

uni-app支付宝,uniapp支付宝沙箱支付报错,uni.requestPayment,uniAPP App支付宝支付提示错误requestPayment:fail [payment支付宝:62009]未知错误,UNI-APP支付宝报错"code": -100,uniapp 解决安卓App使用uni.requestPayment实现沙箱环境支付宝支付报错,uniapp安卓app使用支付宝的沙箱环境支付时报了这个错,安卓端app支付宝支付,在沙箱测试环境测支付,提示“商家订单参数异常,请重新发起付款,选择

🏆 前端领域优质创作者 9535

基于Django,keras,axios, echats的智能股票分析系统源码+文档(集成LSTM的实践序列预测算法).zip

简介:本资源为基于Django、Keras、axios和echarts的智能股票分析系统源码及文档,集成了LSTM的实践序列预测算法。通过深度学习模型对股票市场数据进行分析和预测,为用户提供大盘指数行情、股票对比分析、个股信息分析等功能。此外,还包括明日股价预测、股价区间预测、股价走势预测、股价涨跌预测等实用功能。项目旨在提供一个高效的学习和实践平台,适合计算机相关专业的学生和企业员工进行深入学习和实践。特点:使用Django框架构建Web应用,具备强大的后台管理能力。采用Keras库实现深度学习模型,支持快速实验和部署。利用axios进行异步请求,提高页面响应速度。使用echarts进行数据可视化,提供直观、生动的图表展示。集成了LSTM深度学习神经网络,有效处理时间序列数据,提升预测精度。适用人群:计算机相关专业的学生对深度学习和股票分析感兴趣的企业员工Web开发和数据科学领域的学习者和实践者

上一篇: C++学习步骤
下一篇: 如何正确简单的创建dll
iinel
博客等级 码龄19年 15粉丝 65原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值