C++中字符数组和字符串string
字符数组
C++中字符数组用char str[]能够用来表示一个字符串。
(1) 数组的大小和字符串的长度。
数组的大小一定要大于字符串的长度,由于系统会自己主动补上一个’\0’作为字符串的结束标志。
当然对于未初始化的也补’\0’.
#include <iostream>
#include <string> using namespace std; int main()
{
char str[11] = "I am happy"; // 系统会自己主动补上'\0'空字符作为结束标志,,未有初始化的也补'\0'
//char str[10] = "I am happy"; // 出错 系统自己主动补上'\0' 此时字符数组长度不够
//char str[13] = "I am happy"; // 后面未有初始化的也补上'\0' 为 I am happy\0\0\0
if(str[10] == '\0')
{
cout << "hello world!!" << endl;
} cin >> str; // 输入输出
cout << str << endl;
return 0;
}
另外注意:
(1)
char *val = "abcdef"; // 在栈上存放了一个指针变量val,使其指向常量区的abcdef。。普通情况下常量区比較大,大多数情况下f后面常量区没有分配出去,即为NULL,有时会遇到不为NULL。就会出现故障。
cout << val << endl; // 输出结果为abcdef 直到空指针为止
(2)
char b[2]={'b','a'};
char a[4]={"abc"};
cout << b <<endl; // 输出为ba乱码 因为没有\0 不会截止
cout << a << endl; /// 输出结果为abc 直到\0为止
cout << strlen(a) << endl; // 结果为3
(3)
char *val = "abcdef";
cout << val << endl; // 输出结果为abcdef 直到空指针为止
cout << strlen(val) << endl;
char *new_val = new char[strlen(val)+1]; // new_val 为val的值 最后一位以\0填充
strncpy(new_val, val, strlen(val)+1);
cout << new_val<< endl; // 输出为abcdef 直到\0截止
函数原型char*strncpy(char*dest,char*src,size_t n);
(c/c++)复制字符串src中的内容(字符。数字、汉字....)到字符串dest中,复制多少由size_tn的值决定。
假设src的前n个字节不含NULL字符。则结果不会以NULL字符结束。
假设src的长度小于n个字节,则以NULL填充dest直到复制完n个字节。src和dest所指内存区域不能够重叠且dest必须有足够的空间来容纳src的字符长度+'\0'。来自:http://baike.baidu.com/link?
url=lxi_91JHsW-4omg_8DcV_3APvcwUL9oFFtku6V-VR_t9-Pf5DJzVu886fvGCM_YzXhd-hXdwqMyiGcZwWGXR-_
(4)
int
*pa = '\0';
int *pb = 0;
int *pc = NULL; // 三者等效
(5)
int
a[5]; sizeof(a) 就等于5*sizeof(int) = 20;
假设 是 int*p = new int[5]; 此时p为一个指针那么sizeof(p) 就等于4 == sizeof(int*) 包含double*,void* 或者类类型指针等的字节数都为4
char
*p = "abc" 那么sizeof(p) == 4 由于p是一个指针。
char
p[4] = "abc", 那么sizeof(p) == sizeof(char) * 4 = 4;;;此时为数组
char
*p[5]; 由于[]优先级高于*,所以把它看做类似于int p[5],,那么就是定义了一个长度为5的数组。仅仅只是数组中的元素都是char*指针,即指向char类型的指针。
所以sizeof(p) = sizeof(char*)*5 = 20,。而*p是一个指针,所以sizeof(*p) == 4 == sizeof(指针)————————一个数组 类比于char p[5][] 第二维不确定
char
(*p)[5]; 类比于 int a[5],此时*p等于a,那么就是说p是一个指针。指向一个指向字符数组的指针。,相当于char p[][5],,
所以sizeof(p) == sizeof(指针) = 4,,而*p是一个数组的首地址,。所以sizeof(*p) == sizeof(char)*5 = 5.————p是一个指针,类比于char p[][5] 第一位不确定
假设p的值为0x00的话 那么p++的值就为0x05,
p尽管是一个指针。但所指向的对象为一个数组的首地址,其大小为sizeof(char)*5,,所以p+1,这里加的是一个数组的字节数即为sizeof(char)*5;;;;;;; 而假设 int *px= new int,。, 此时px指向的对象为int,其大小为sizeof(int), 所以p+1加的是sizeof(int)字节。
。。如p(int*类型)所指的内存地址为0x0000,,即p值为0x0000。那么p+1所在的内存地址就为0x0004,通常我们将一个字节作为一个内存单元进行存放。。
一个指针变量加(减)一个整数并非简单地将原值加(减)一个整数,而是将该指针变量的原值(是一个地址)和它指向的变量所占用的内存单元字节数加(减)。
下面代码会输出hello world
#include <stdio.h>
#define TESTSIZE 20
int main(void)
{
char szTest[][TESTSIZE] = {"hello", "world"};
char (*p)[TESTSIZE]; p = szTest;
for(int i = 0; i < sizeof(szTest)/TESTSIZE; i++)
{
printf("%s ", p + i);
}
}
strlen与sizeof
int main(){ char dog[] = "wang\0miao";
cout << strlen(dog) << " " << sizeof(dog) << endl; // 4, 10 strlen遇到\0就结束了且不包含\0 char xx[] = {"hello"};
cout << strlen(xx) << " " << sizeof(xx) << endl; // 5, 6 char *val = "abcde";
cout << strlen(val) << " " << sizeof(val) << endl; // 5, 4 val是一个指针。大小为4个字节 cout << sizeof(long) << sizeof(bool) << endl; // 4, 1
return 0;
}
strlen遇到\0就结束了,且不包含\0 这个字符。
即使char a[10]={"hello"}; strlen(a)返回的仍然是5。 而sizeof(a)会等于10
char a[]="ABCDEF";char b[]={'A','B','C','D','E','F'}; a的长度比b的长。。多了一个\0,,可是strlen(b)会是一个任意值。由于b没有以\0结束
(6) char *val; val = "helloworld"; 是正确的;; 而char val[10]; val= "helloworld"; 是错误的。
char b[]={'A','B','C'};
cout << strlen(b) <<" "<< sizeof(b) << endl; // 15 3
char d[]="ABC";
cout << strlen(d) << " " << sizeof(d) << endl; //3 4
(2)getline()
getline函数能够读取文本或者输入流的一行,此时包含前面输入的空格,仅仅到回车换行才结束
#include <fstream>
#include <iostream>
#include <string> using namespace std;
int main()
{
ifstream in("E:\\algorithmZack\\testString\\input.txt");
if(!in)
{
cerr << "some errors happened";
return -1;
}
string str;
while(getline(in, str)) /// getline 从文件input.txt中按行读取文件
// while(getline(cin, str)) // 从输入流中按行读取 不包含换行符
{
cout << str << endl;
}
return 0;
}
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTHU1OTcyMDM5MzM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
(3)比較,连接,赋值。实际长度用函数strcmp, strcat, strcpy,strlen
參见blog:http://see.xidian.edu.cn/cpp/biancheng/view/158.html
字符串string
(1)String能够看做一个类库。须要有包括头文件#include <string>.
操作包含:连接(+=,append) 赋值(=, assign) 比較(>=,compare) 查找(find)
替换(replace) 删除(erase) 插入(insert) 字串(substring) 交换(swap)
特性(length sizec_str) 正反向迭代器(interator reverse_iterator)
当中使用append,assign,compare的优点在于參数能够为字符数组
具体见blog:http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html
(2)一个简单的样例
从txt中读入以空格为单位的字符串,并对其进行去重排序输出
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
ifstream in("E:\\algorithmZack\\testString\\name.txt"); // fstream
string str;
vector<string> vec; //vector
while(getline(in, str)) // string
{
int pos = 0;
while((pos = str.find_first_of(' ', pos)) != string::npos)
{
vec.push_back(str.substr(0, pos));
pos ++;
}
vec.push_back(str.substr(str.find_last_of(' ')+1)); // 将最后一个字符放入进来
}
sort(vec.begin(), vec.end()); // algorithm
/*注意这里去掉了相邻的反复元素。因此在调用unique之前须要排序 但vec大小没变。在其后面加入了两个空格。 可是对于int,则将反复的元素放在后面 */
vector<string>::iterator it = unique(vec.begin(), vec.end()); // algorithm 返回去重后最后一个元素
copy(vec.begin(), it, ostream_iterator<string>(cout, "\n")); // iterator ostream_iterator<string> iterator
cout << endl;
copy(vec.begin(), vec.end(), ostream_iterator<string>(cout, "\n"));
/*for(vector<string>::iterator iter = vec.begin(); iter != vec.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;*/
return 0;
}
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTHU1OTcyMDM5MzM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
注意:这里的unique去掉了vector<string>中反复元素,但其大小没有变。反复的元素用空格取代放在其后面。可是对已vector<int>,则将反复的元素放在后面。
(3)copy函数
Copy函数包括在头文件#include<iterator>头文件里。
主要有三个经常使用的使用方法
copy(IteratorInput it1, IteratorInput it2, IteratorOnput it3) // algorithm
1: 用数组对vector<T>进行赋值
2:用cin对vector<T>进行赋值
3:将vector<T> 进行输出
copy函数原型解释见blog:http://blog.csdn.net/jerryjbiao/article/details/7376088
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <string>
using namespace std; int main()
{
vector<int> vec;
cout << "hello world!!" << endl;
//int a[] = {3,2,1,1,2,3};
//copy(a, a+6, back_inserter(vec));
//vec.resize(6);
// copy(a, a+6, vec.begin());
copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(vec));
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
sort(vec.begin(), vec.end());
vector<int>::iterator it = unique(vec.begin(), vec.end());
copy(vec.begin(), it, ostream_iterator<int>(cout, " ")); // 输出
return 0;
}
(4)一个简单的样例
过滤一行开头和结尾的全部的非英文字符。这里仅仅是为了说明find函数find_first_of函数的差别。Find是从pos開始查找字符串s在当前串中的位置;而find_first_of是从pos開始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。
如: str.find(str1) 是返回字符串str1 第一次出现字符串str中的位置,假设找不到则返回string::npos(结束标志). str.find_first_of(ch)是返回字符ch第一次出如今字符串str中的位置,假设找不到则返回string::npos. str.find_first_of(str1)是返回str的第一个能够在字符串str1中找到的字符在str中的下标
如str=“-------hello,world------------”; str1 = "abcdefghidklmnopk"; 则str.find_first_of(str1) ,从str第一个字符開始。发现第一个字符h能够在str1中找到。因此返回字符h在str中的下标7
#include <string>
#include <iostream>
using namespace std; int main()
{
string strinfo = "//*----Hello world!.....----";
string strset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; int first = strinfo.find_first_of(strset);
if(first == string::npos)
{
cout << "not find any characters" << endl;
return -1;
} int last = strinfo.find_last_of(strset); if(last == string::npos) //string::npos =-1 没有找到 结束标志
{
cout << "not find any characters" << endl;
return -1;
}
cout << strinfo.substr(first, last - first +1) << endl; string str = "hello world!!!";
string str2 = "hlo";
// 注意 find和find_first_of()差别非常大
int j = str.find(str2); // 从pos開始查找字符串str2在当前串str中的位置
int i = str.find_first_of(str2); // 从pos開始查找当前串str中第一个字符在str2的前n个字符组成的数组里的字符的位置。
cout << i << endl; return 0;
}
參见其他blog:1:http://www.cplusplus.com/reference/string/string/:
2:http://blog.csdn.net/yangtrees/article/details/7577263
3:http://www.cnblogs.com/uniqueliu/archive/2011/07/28/2119328.html
4:http://blog.csdn.net/jerryjbiao/article/details/7376088
5:http://www.cnblogs.com/zkliuym/articles/909245.html
一)64位系统和32位有什么差别?
1、64bit CPU拥有更大的寻址能力,最大支持到16GB内存,而32bit仅仅支持4G内存
2、64位CPU一次可提取64位数据。比32位提高了一倍,理论上性能会提升1倍。
但这是建立在64bit操作系统,64bit软件的基础上的。
什么是64位处理器?
之所以叫做“64位处理器”,是由于电脑内部都是实行2进制运算,处理器(CPU)一次处理数据的能力也是2的倍数。8位处理器、16位处理器、32位处理器和64位处理器,其计数都是2的倍数。一次处理的数据越大,该电脑处理信息的能力越来越大;因此64位处理在先天就比32位处理器具有高速的能力。
那为什么不用更高级的128位处理器呢?由于位数越高。处理器芯片的设计也就越复杂,眼下的技术水平临时无法制造这么复杂的芯片。
64位处理器之失
※硬件———缺乏驱动程序,非常多现有硬件无法使用
※软件———操作系统不是问题。可是软件出现不兼容难题
64位处理器之得
※硬件———更快的运行速度,更大的内存管理
※软件———最新的尖端软件首先出如今64位平台
(二)数据类型相应字节数
程序执行平台
不同的平台上对不同数据类型分配的字节数是不同的。
个人对平台的理解是CPU+OS+Compiler。是由于:
1、64位机器也能够装32位系统(x64装XP);
2、32位机器上能够有16/32位的编译器(XP上有tc是16位的。其它常见的是32位的)。
3、即使是32位的编译器也能够弄出64位的integer来(int64)。
以上这些是基于常见的wintel平台,加上我们可能非常少机会接触的其他平台(其他的CPU和OS)。所以个人觉得所谓平台的概念是三者的组合。
尽管三者的长度能够不一样,但显然相互配合(即长度相等。32位的CPU+32位的OS+32位的Compiler)发挥的能量最大。
理论上来讲 我认为数据类型的字节数应该是由CPU决定的,可是实际上主要由编译器决定(占多少位由编译器在编译期间说了算)。
经常使用数据类型相应字节数
可用如sizeof(char),sizeof(char*)等得出
32位编译器:
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit。也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
64位编译器:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节
16位操作系统中,int 占16位;在32位操作系统中,int 占32位。 可是如今人们已经习惯了 int 占32位,因此在wd=64%E4%BD%8D%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1d9PyRzrj6zuADsrAcduHnk0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6K1TL0qnfK1TL0z5HD0IgF_5y9YIZ0lQzqlpA-bmyt8mh7GuZR8mvqVQL7dugPYpyq8Q1nzPHmznHmkr0" rel="nofollow" style="color:rgb(45,100,179); text-decoration:none">64位操作系统中,int 仍为32位。64位整型用 long long 或者 __int64
C++中字符数组和字符串string的更多相关文章
- C语言中字符数组和字符串指针分析
这几天搞Unix上的C程序,里面用到了很多字符数组和字符串指针,我记得在学完C语言后相当一段时间里,对指针这个东西还是模模糊糊,后来工作也没怎么 用到过C,虽然网上这类的文章也有很多,还是决定自己在这 ...
- java中字符数组与字符串之间互相转换的方法
public static void main(String[] args) { //1.字符数组 转换成 字符串 //(1)直接在构造String时转换 char[] array = new cha ...
- C#编程中的Image/Bitmap与base64的转换及 Base-64 字符数组或字符串的长度无效问题 解决
最近用base64编码传图片遇到了点问题,总结下. 首先总结下base64编码的逻辑,来自网络:https://www.cnblogs.com/zhangchengye/p/5432276.html ...
- [日常] C语言中的字符数组和字符串
c语言字符数组和字符串:1.存放字符的数组称为字符数组 char str[]2.'\0'也被称为字符串结束标志3.由" "包围的字符串会自动在末尾添加'\0'4.逐个字符地给数组赋 ...
- C语言中整形数组、字符数组、字符串的区别
一. 第一 整型数组的存放,数组最后是不加'\0'的,字符串会自动加上,因此存放字符的时候数组的大小要比实际字符的多一个 第二 整型数组 每一个单元是4个字节的,字符串是一个一个字符存放的,每个字符占 ...
- c语言中的字符数组与字符串
1.字符数组的定义与初始化 字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素. char str[10]={ 'I',' ','a','m',' ',‘h’,'a','p','p','y ...
- Java中字符数组、String类、StringBuffer三者的相互转换
一.StringBuffer与String的相互转换 1.将StringBuffer转换成String StringBuffer类成员toString函数可将其转换成String类型. StringB ...
- C++中字符数组与string的相互转换
字符数组转化成string类型char ch [] = "ABCDEFG";string str(ch);//也可string str = ch;或者char ch [] = &q ...
- C#中字符数组,字节数组和string之间的转化
转自:http://blog.csdn.net/wangxiaoqin00007/article/details/17675419 NDC(NetworkDiskClient)的界面和后台程序之间用S ...
随机推荐
- 刷题总结——date(ssoj)
题目: 题目背景 SOURCE:NOIP2015-SHY-9 题目描述 小Y和小Z好不容易有机会相见啦,可是邪恶的小H却不想让他们相见.现在有一些城市,城市之间有双向路径相连,有路径相连的城市之间可以 ...
- 浅谈android反调试之 转发端口
反调试方案: 我们最通常使用的动态工具是IDA, IDA的动态调试端口默认为23946,我们可以通过/pro/net/tcp 查看android 系统所有TCP Socket 启动android_se ...
- Java面试题之谈谈reactor模型
reactor是什么? 事件驱动 可以处理一个或多个输入源 通过Service Handle同步的将输入事件采用多路复用分发给相应的Request Handler(一个或多个)处理 具体可参考:htt ...
- offsetWidth clientWidth scrollWidth 三者之间的区别和联系
scrollWidth:对象的实际内容的宽度,不包边线宽度,会随对象中内容超过可视区后而变大. clientWidth:对象内容的可视区的宽度,不包滚动条等边线,会随对象显示大小的变化而改变. off ...
- 转 浅谈C++中指针和引用的区别
浅谈C++中指针和引用的区别 浅谈C++中指针和引用的区别 指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法. 1.指针和引用的定义和性 ...
- 标准C程序设计七---33
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- Struts+ibatis-学习总结二
1封装json 在Action中以传统方式输出JSON数据 这一点跟传统的Servlet的处理方式基本上一模一样,代码如下 public void doAction() throws IOExcept ...
- 编译 Android 版本的 Opus 音频编解码库的方法
Opus 音频编解码库是 Speex 音频编解码库的下一代版本,从编解码性能以及质量上来讲都有了长足的进步.Opus 的编译非常简单,但是官方并未给出详细的 Android 版本编译指南,查找了大量资 ...
- Apple激活日期查询
需要输入的信息为苹果产品的序列号 查看您的保修服务和支持期限 - Apple 支持 或者通过果粉查询网站获取结果
- DELPHI跨平台编译开关
DELPHI跨平台编译开关 DELPHI 现在是跨平台的开发工具,已经不仅仅针对WINDOWS OS. 跨平台的时候,一些WINDOWS特有的API或语法是不能用的,必须使用跨平台的新语法,要用编译开 ...