一、c中字符串的处理
char *p=”computer”;其最后一个是’\0’,并且操作的时候以遇到’\0’认为字符串结束了。
可以以下标的形式输出字符串中的字符。
不可以更改常量字符串,因为这样是放到了静态常量区。
这样就更改了。”computer”存储的位置更改了。
为什么a输出不了,因为数组p[10]能存10个字符,布局如下
‘c’ |
‘o’ |
‘m’ |
‘p’ |
‘u’ |
‘t’ |
‘e’ |
‘r’ |
‘\0’ |
‘a’ |
字符串是以‘\0’结尾的。检测到‘\0’即认为字符串结束。故a输出不了。
字符串只能存在字符数组中。
a的ASCLL码为97,所以输出整形就是97.
在c中没有字符串类型,所以只能采用字符指针或字符数组进行操作,对于一个字符串,若赋给字符指针,则字符串存放的位置是静态常量区,不可对其更改。若赋给字符数组,则字符串就放在系统分给该字符数组的内存中,可以对其更改。存放的结果相当于存入一个个字符,例如”computer”,放在长度为10的字符数组中,布局如下:
‘c’ |
‘o’ |
‘m’ |
‘p’ |
‘u’ |
‘t’ |
‘e’ |
‘r’ |
‘\0’ |
‘\0’ |
字符串是以‘\0’结尾的。检测到‘\0’即认为字符串结束。
sprintf_s函数功能:将数据格式化输出到字符串,
int sprintf_s(char*buffer,size_t sizeOfBuffer,const char *format [,argument] ...);
需要包含的头文件:stdio.h
注意:sprintf_s()是sprintf()的安全版本,通过指定缓冲区长度来避免sprintf()存在的溢出风险。
c++中可以使用stringstream类
描述:是对istringstream和ostringstream类的综合,支持<<,>>操作符,可以进行字符串到其它类型的快速转换
作用:
1、stringstream通常是用来做数据转换的
2、将文件的所有数据一次性读入内存
注意加上stream.clear();否则每次输出都是10. stream.clear()相当于把以前的流清空了。由于stringstream构造函数会特别消耗内存,似乎不打算主动释放内存(或许是为了提高效率),但如果你要在程序中用同一个流,反复读写大量的数据,将会造成大量的内存消耗,因些这时候,需要适时地清除一下缓冲 (用 stream.str("") )。
二、数组或字符串的长度
1、sizeof()---求所占的字节数
#include <string>
#include <iostream>
using namespace std;
int main()
{
//(1)、对于整型字符型数组
int A[] = { 1, 4, 5, 2, 8, 6, 0 };
//求整型数组A所占的字节数
cout << "sizeof(A) = " << sizeof(A) << endl; //整型数组A所占的总空间的字节数
cout<<"sizeof(A) / sizeof(int)="<<sizeof(A) / sizeof(int)<<endl;//此时i表示数字数组的元素个数
char B[] = { 'a', 'e', 's', 'r', 'q' };
//求字符数组的所占的字节数
cout << "sizeof(B)=" << sizeof(B) << endl;//结果为5*sizeof(char)=5
//求字符数组的元素个数
cout << "sizeof(B) / sizeof(char)=" << sizeof(B) / sizeof(char) << endl;
char C[] = "abcde";
cout << "i = sizeof(C)=" << sizeof(C) << endl;//字符数组C所占的字节空间,为6,最后一个为’\0’
//(2)、对于整型或字符型指针
int *p=NULL;
int D[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
p = D;
cout << "sizeof(*p)="<<sizeof(*p) << endl;//p所指的整型数组A的第一个元素A[0]的所占字节数
cout << "sizeof(p)=" << sizeof(p) << endl;
cout << *p << endl; //输出A[0]即1
cout << p << endl; //输出的结果为整型指针所指向的地址 0x……
char *p1;
char E[] = { 'a', 's', 'e', 'r' };
p1 = E; //字符指针赋值,或char *p=B;这样为字符指针初始化赋值
cout << "sizeof(p1)" << sizeof(p1) << endl;//p为字符指针,指针的大小为定值,为4
cout << "sizeof(*p1)" << sizeof(*p1)<< endl;//这是指B[0]所占空间的大小
system("pause");
return 0;
}
2、strlen()---字符数组或字符串所占的字节数
strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止(注意存储在数组中时易出错),然后返回计数器值。 --就是指实际字符串或字符数组的实际长度(不是所占空间的字节数)。
#include <string>
#include <iostream>
using namespace std;
class Syf
{
int i;
int j;
char k;
};
Syf x;
class A1
{
};
class A2
{
};
class B1 :public A1
{
};
class C1 :virtual public B1
{
};
class D1 :public A1, public A2
{
};
int main()
{
char A[6] = { 'a', 'b', '\0', 'd', 'e', 'r' };
cout << "strlen(A)="<<strlen(A) << endl;//因为到’\0’结束,故实际A[]只有2个元素
char *str = "abcde";
cout <<"strlen(str)="<< strlen(str) << endl;
//char A[6]={"abcdef"}; //error C2117: 'abcdef' : array bounds overflow
//针对字符指针
char C[] = { "abcdef" };
char *p1 = C;
cout << "strlen(p1)="<<strlen(p1) << endl;
char D[] = { 'a', 'c', 'q', 'f', 'w' };
//这样,由于没指定D的内存分配大小,用strlen求其长度会造成错误。
//如果为char D[5]={'a','c','q','f','w'};这样再用strlen求其长度也会造成错误,当D[]之中的数
//大于5才不会造成错误。 似乎因为strlen是判断\0才结束的。
cout << "strlen(D)=" << strlen(D) << endl;
//针对其他结构
cout << "sizeof(Syf)="<<sizeof(Syf) << endl; //结果 12 == = 》内存补齐
cout <<"sizeof(x)="<< sizeof(x) << endl;// 结果 12 同上
//解释一下,在class X中,成员中最大的所占的空间为int类型所占的空间4个字节,故内存补齐。
//有关空类
//一个空类占多少空间?多重继承呢?
cout << "sizeof(A1): " << sizeof(A1) << endl;
cout << "sizeof(B1): " << sizeof(B1) << endl;
cout << "sizeof(C1): " << sizeof(C1) << endl;
cout << "sizeof(D1): " << sizeof(D1) << endl;
system("pause");
return 0;
}
表明空类所占空间为1个字节,单一继承的空类空间也为1,多重继承的空类空间还是1,但虚继承涉及虚表(虚指针),所以sizeof(C)为 4。
3、sizeof()与strlen()区别
sizeof()返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符,strlen是函数。
4、c++中的字符串string的长度
为了兼容等,这两个函数一样。 length是因为沿用C语言的习惯而保留下来的,string类最初只有length,引入STL之后,为了兼容又加入了size,它是作为STL容器的属性存在的,便于符合STL的接口规则,以便用于STL的算法。
string类的size()/length()方法返回的是字节数,不管是否有汉字。