C语言中的字符串
C语言不存在字符串数据类型,其通过一个以’\0’结尾的字符数组实现;所有字符串都是以\0结尾的,所有以\0结尾的字符数组都可以看作字符串。 字符数组的定义,常见有如下几种形式: char a[10] ={‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’,‘h’,‘i’,‘j’}; char a[10] ={‘a’,‘b’,‘c’,‘d’,‘e’}; char c[ ] ={‘C’,‘h’,‘i’,‘n’,‘a’}; char c[ ] =“China”; 举例: char c[5] = “China”; //非法赋值,后面的字符串是6个字符 char c[6] = “China”; //合法,这种赋值方式只能在数组定义并初始化的时候 不能用赋值语句将一个常量字符串或字符数组赋值给另一个字符数组 str1[ ] = “China”; //非法,只有在字符串定义时合法 str2 = “China”; //非法 str3 = str2; //非法 字符数组的输出 char str1[ ] = “C++language”; cout<<“String1:”<<str1<<endl;
关于字符数组的几点说明: 1、定义char a[5],则说明,a是个字符数组,在内存中占五个字节空间;如果用a来存储字符串,则最多只能有4个有效字符,必须给\0留个空间; 2、a按字符串来算长度是从a这个地址开始,计数到\0字符,这之间的字符个数是字符串a的长度;一般常用strlen()函数来获取字符串长度; 3、计算a的大小用sizeof命令,sizeof(a)得到的是a在内存中占的字节数; 4、字符串与字符数组不能混为一谈。它们相同在形式上,区别就在,字符串一定有\0结束符,而数组不需要!什么是字符串?就是以双引号引起来的数据才叫字符串。字符数组可以存储字符串; 5、C语言汇总不存在字符串数据类型,其通过一个以’\0’结尾的字符数组实现;;在C++编程中建议使用string替换C字符串; 6、char p = “abc”;是在文字常量区分配了一块内存放"abc",然后在栈上分配一地址给p并指向这块地址; 7、char p是一个指针,根本没分配内存,他指向的"abc123ABC" 是只读的,不能改变
数组: 数组名代表数组元素的地址; 数组名相当于指向数组第一个元素的指针,即a与&a[0]等价; 数组名a是地址常量,不是变量,不能给a赋值; a[i]等价于*(pointer+i),等价于pointer[i]
&a是指向数组的指针;&a+1将跨越16个字节;&a相当于管辖范围上升了一级; a是数组的第一个元素a[0];即a等价于a[0];*a相当于管辖范围下降了一级;
数组三条规律 数组名相当于指向数组第一个元素的指针; &E相当于把E的管辖范围上升了一个级别; *E相当于把E的管辖范围下降了一个级别;
C++语言中的字符串
在C++中有两种字符串的概念: 1、string类: 由于string为类,定义时实际上是定义了一个对象,而初始化方式也就决定了调用何种构造函数来进行构造 string a;//定义一个空字符串。 string b=“test string”;//定义一个字符串并初始化为test string。 关于string类的详细使用说明,在其他博文介绍。 2、字符数组: C++继承了C语言的概念,而在C语言中字符串指的是字符数组,并约定以\0作为结束符 char a[20] = “test string”; //定义一个字符串并初始化为test string;;char *b = “test string”; //与a类似,但这个是直接使用常量字符串的地址,所以字符串b是只读的。
C语言str系列库函数
[strcmp] strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数 函数原型:extern int strcmp(const char *s1,const char *s2);//s1=s2,则返回零;s1<s2,则返回负数;s1>s2,则返回正数。
char cA[6] = "hello";
char *cB = "hello";
int ret = strcmp(cA,cB);
[strcpy] strcpy,即string copy(字符串复制)的缩写,原型声明:char strcpy(char dest, const char *src); 功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间 说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串,返回指向dest的指针。
char printInfo[50];
memset(printInfo, 0x00, 50);
strcpy(printInfo, "CB532测试打印信息");
[strncpy] strncpy函数用于将指定长度的字符串复制到字符数组中,函数原型: char *strncpy(char *dest, const char *src, int n);//表示把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回被复制后的dest。
char src[] = "It's Monday and it's raining";
char dest[40];
strncpy(dest,src,10);
strncpy(dest,src,strlen(src)+10);
[memcpy] void *memcpy(void *dest, const void *src, size_t n);//用来将src地址处的内容拷贝n个字节的数据至目标地址dest指向的内存中去,函数返回指向dest的指针
char *s= "Golden Global View";
char d[20];
memcpy(d,s,strlen(s));
[memset] void *memset(void *s,int c,size_t n) //将已开辟内存空间 s 的首 n 个字节的值设为值 c(给空间初始化),返回s //memset函数按字节对内存块进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)
char szVerBuf0[512+1];
memset(szVerBuf0,0x00,sizeof(szVerBuf0));
[strlen] extern unsigned int strlen(char *s); strlen所作的是一个计数器的工作,它从内存的某个位置开始扫描,直到碰到第一个字符串结束符’\0’为止,然后返回计数器值(长度不包含’\0’)。
char aa[200]="Hello,World!";
printf("strlen(aa)=%d.\n",strlen(aa));
printf("sizeof(aa)=%d.\n",sizeof(aa));
[strstr] char *strstr(const char *haystack, const char *needle);//在字符串 haystack 中查找第一次出现字符串 needle 的位置并返回,不包含终止符 ‘\0’,如果未找到则返回 null。
char haystack[20] = "RUNOOB2";
char needle[10] = "NOOB";
char *ret;
ret = strstr(haystack, needle);
printf("substr:%s\n", ret);
[strcspn] size_t strspn(const char *s, const char * accept);//若strcspn()返回的数值为n, 则代表字符串s 连续有n 个字符都包含accept 内的字符
char *s="Golden Global View";
cout<<strspn(s, " ")<<endl;
cout<<strspn(s, "loG")<<endl;
cout<<strspn(s, "nedloG")<<endl;
cout<<strspn(s, "nGew")<<endl;
[strcat] char *strcat(char *dest, const char *src);//把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。
char src[50], dest[50];
strcpy(src, "This is source");
strcpy(dest, "This is destination");
strcat(dest, src);
printf("最终的目标字符串: |%s|", dest);
[substr] basic_string substr(size_type _Off = 0,size_type _Count = npos) const; //_Off:所需的子字符串的起始位置。字符串中第一个字符的索引为 0,默认值为0。 //_Count:复制的字符数目 //返回值:一个子字符串,从其指定的位置开始
[memcmp] int memcmp(const void *str1, const void *str2, size_t n)) 把存储区 str1 和存储区 str2 的前 n 个字节进行比较 str1 – 指向内存块的指针。 str2 – 指向内存块的指针。 n – 要被比较的字节数 返回值 如果返回值 < 0,则表示 str1 小于 str2。 如果返回值 > 0,则表示 str1 大于 str2。 如果返回值 = 0,则表示 str1 等于 str2。
[memchr] void *memchr(const void *str, int c, size_t n) 在参数 str 所指向的字符串的前 n 个字节中搜索第一次出现字符 c(一个无符号字符)的位置。 参数 str – 指向要执行搜索的内存块。 c – 以 int 形式传递的值,但是函数在每次字节搜索时是使用该值的无符号字符形式。 n – 要被分析的字节数。 返回值 该函数返回一个指向匹配字节的指针,如果在给定的内存区域未出现字符,则返回 NULL。
[printf] printf()是C语言标准库函数,用于将格式化后的字符串输出到标准输出。标准输出,即标准输出文件,对应终端的屏幕。printf()申明于头文件stdio.h int printf ( const char * format, … );//函数原型 返回值: 正确返回输出的字符总数,错误返回负值,与此同时,输入输出流错误标志将被置值,可由指示器ferror来检查输入输出流的错误标志。 printf的格式控制字符串组成如下: %[flags][width][.prec][length]type %[标志][最小宽度][.精度][类型长度]类型
[fprintf] fprintf()用于文件操作,函数原型 #include <stdio.h> int fprintf( FILE *stream, const char *format, … ); fprintf()函数根据指定的format(格式)发送信息(参数)到由stream(流)指定的文件.因此fprintf()可以使得信息输出到指定的文件 stdout – 标准输出设备 stderr – 标准错误输出设备 stdout和stderr区别:都是默认向屏幕输出,stdout是行缓存的,而stderr是无缓存的,直接输出。
//示例:输出HelloMary 到文件output.txt char name[20] = “Mary”; FILE *out; out = fopen( “output.txt”, “w” ); if( out != NULL ) fprintf( out, “Hello %s\n”, name ); fclose(out);
[sprintf] 函数功能:把格式化的数据写入某个字符串 函数原型:int sprintf( char *buffer, const char *format [, argument] … ); 返回值:字符串长度(strlen) //示例 char name[20] = “make”; int age = 20; char desc[50]; sprintf(desc,“my name is %s,age:%d.”,name,age); printf(“:%s\n”,desc);//输出:my name is make,age:20
sizeof()、strlen()、length()和size()
sizeof():返回所占总空间的字节数 (1)、对于整型字符型数组 (2)、对于整型或字符型指针 sizeof(…)是运算符,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。
strlen():返回字符数组或字符串所占的字节数 (1)、针对字符数组 (2)、针对字符指针 strlen(char*)函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个’\0’,如果你只定义没有给它赋初值,这个结果是不定的,它会从aa首地址一直找下去,直到遇到’\0’停止。
c/c++ strlen(str)和str.length()和str.size()都可以求字符串长度。 其中str.length()和str.size()是用于求string类对象的成员函数 strlen(str)是用于求字符数组的长度,其参数是char*。
举例: 1)char* ss = “0123456789”; sizeof(ss)为4,ss是指向字符串常量的字符指针,sizeof 获得的是指针所占的空间,则为4 sizeof(*ss)为1,ss是第一个char字符,则为1 2)char ss[] = “0123456789”; sizeof(ss)为11,ss是数组,计算到’\0’位置,因此是(10+1) sizeof(ss)为1,ss是第一个字符 3)char ss[100] = “0123456789”; sizeof(ss)为100,ss表示在内存中预分配的大小,1001 strlen(ss)为10,它的内部实现用一个循环计算字符串的长度,直到’\0’为止。 4)int ss[100] = “0123456789”; sizeof(ss)为400,ss表示在内存中预分配的大小,1004 strlen(ss)错误,strlen参数只能是char,且必须是以’\0’结尾 5)char[] a={‘a’,‘b’,‘c’}; sizeof(a)的值应该为3。 char[] b={“abc”}; sizeof(b)的值应该是4。 若string str={‘a’,‘b’,‘c’,‘\0’,‘X’}; 那么sizeof(str)为5,strlen(str)为3。
string中length()和size() c++中的size()和length()没有区别 这两个函数一样。 length()是因为沿用C语言的习惯而保留下来的,string类最初只有length(),引入STL之后,为了兼容又加入了size(),它是作为STL容器的属性存在的,便于符合STL的接口规则,以便用于STL的算法。 string类的size()/length()方法返回的是字节数,不管是否有汉字 汉字一般占用2个字节,数字和英文字母占用1个字节 特殊字符一般英文输入法是占用1个字节,中文输入法占用2个或4个字节,比如英文感叹号占用1个字节,中文输入的感叹号占用2个字节
Qt中的字符串
Qt中除了可以使用C/C++中的字符串,还封装了QString类用于操作字符串。 Qt使用printf打印无输出问题 尝试在QT中使用printf打印结果不实时输出,是因为打印结果在缓冲区未被释放,所以无法显示,解决方法: printf在glibc中默认为行缓冲,遇到以下几种情况会刷新缓冲区,输出内容: (1)缓冲区填满; (2)写入的字符中有换行符\n或回车符\r; (3)调用fflush手动刷新缓冲区;//fflush(stdout);//释放缓冲区 (4)调用scanf要从输入缓冲区中读取数据时,也会将输出缓冲区内的数据刷新。 可使用setbuf(stdout,NULL)关闭行缓冲,或者setbuf(stdout,uBuff)设置新的缓冲区,uBuff为自己指定的缓冲区。也可以使用setvbuf(stdout,NULL,_IOFBF,0); 来改变标准输出为全缓冲。全缓冲与行缓冲的区别在于遇到换行符不刷新缓冲区。
常见字符串转换 [QString转char[]数组] char name[10]; char* ptr; QString str = ui->namelineEdit->text(); ptr = str.toLatin1().data(); memcpy(p->name,ptr,10); //就是这一句,必须加,不然只是把指针指向了值,并没有赋值
[char[]数组转QString] char c[]=“12ff”; QString str=QString(QLatin1String?);
[QString 转换为 char*] 方法1: QString str; char* ch; QByteArray ba = str.toLatin1(); // must ch=ba.data(); 方法2: QString filename; std::string str = filename.toStdString(); const char* ch = str.c_str();
[char *转为QString] char *ch=“hello!”; QString str(ch); // Qt5 QString str = QString::fromUtf8(ch); // Qt4
[unsigned char* 转QString] unsigned char* ch; std::string str = (char*)ch; QString sstr = QString::fromStdString(str);
[char[]数组之间赋值] char *strcpy(char *dst, const char *src);//把 src 所指向的字符串复制到 dest,返回指向最终的目标字符串 dest 的指针 char a[7] = “abcdef”; char b[4] = “ABC”; strcpy(a,b); printf(“%c”,a[5]);//输出f printf(“%c”,a);//输出ABC\0ef,strcpy碰到\0确实会停止复制,但a中未被覆盖的字符会被保留
[unsigned char转char] unsigned char szBuf[512] reinterpret_cast<char*>(szBuf)
[QString转string] QString.toStdString();
[string转QString] QString::fromStdString(string);
|