C字符串
C语言没有专门用于存储字符串的变量类型,字符串都被存储在 char 类型的数组中,且以字符 \0
结尾;
#include<stdio.h>
int main()
{
char str[4] = "s v"; // char str[3] = "s v";是错的
char str[] = "s v";
char str[4] = { 's', ' ', 'v', '\0' };
printf("sizeof=%zd,strlen=%zd\n", sizeof(str), strlen(str));
}
输出:sizeof=4,strlen=3
//sizeof和strlen得出的结果不同,就是因为计算长度时,sizeof计算全部,strlen不计算‘/0’
上面三种定义字符串的方法结果是一样的;
C字符串定义时可以利用"="号进行初始化,但是以后不能利用"="对C字符串进行赋值。对C字符串的操作需要通过"string"文件中定义的字符串处理函数。例如:
//字符串的初始化
char a[11] = "huanying";//输出长度时 sizeof=11,strlen=8
//字符串的赋值
strcpy(a,"nihao")
//获取字符串的长度,不包括'\0'在内
strlen(a);
printf("%s",a);
也可通过 char* 定义指向字符串的指针
char a[] = " as hh"
char *p = a;// p指向 char 数组 a 的首元素地址,可通过*p 改变数组 a 的内容
字符串的输入
一:使用输入操符来填充一个C字符串变量
例如:
char a[80];
cin>>a;
//以这种方式来读取C字符串时,会忽略最初的空白字符(空格、制表符和换行符),而且输入会在下一个空格或者换行符处停止。
二:使用预定义函数getline获取整行输入(包括空格)
getline函数有两个参数:第一个参数用于接收输入的C字符串变量;第二个参数用于规定getline最多能接收的字符个数。
例如:
char a[80];
cin.getline(a,80);
//当遇到行结束的时候,输入才会停止。
常用字符串函数
char s1[]="I am a student";
char s2[20]="teacher";
char s3[]="student";
int result;
char s4[20],*p;
//串长度
int strlen(char *str)
cout<<strlen(s1)<<endl; //输出14
cout<<strlen(s2)<<endl; //输出7
//串拷贝
char *strcpy(char *str1,char *str2)
strcpy(s4,s2); //s4为"teacher"
//串连接
char *strcat(char *str1,char*str2)
strcat(s2,s3); //s2为"teacherstudent"
//注意:如果使用字符数组存放字符串,strcat函数并不检查第一个数组是否能够容纳第二个字符串,这样多出来的字符串就会溢出到相邻的存储单元而出现问题。
//串比较
int strcmp(char *str1,char *str) //比较的是对应字符的ASCII码值,如果str1>str2,返回1
result=strcmp(s2,s3); //result>0
result=strcmp(s2,s2); //result=0
result=strcmp(s3,s2); //result<0
//串定位
char *strchr(char *str,char ch)
p=strchr(s1,'s'); //找到返回字符在字串中的位置,否则返回-1
strcpy(p,s2); //s1为"I am a teacher"
//在一个串中查找是否存在和另一个串相等的子串
//截取子串形成一个新串
C++字符串
在C++中引入了string类型。
string用法:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str; //定义了一个空字符串str
str = "Hello world"; // 给str赋值为"Hello world"
char cstr[] = "abcde"; //定义了一个C字符串
string s1(str); //调用复制构造函数生成s1,s1为str的复制品
1.cout << s1 << endl;
string s2(str, 6); //将str内,开始于位置6的部分当作s2的初值
2.cout << s2 << endl;
string s3(str, 6, 3); //将str内,开始于6且长度顶多为3的部分作为s3的初值
3. cout << s3 << endl;
string s4(cstr); //将C字符串作为s4的初值
4.cout << s4 << endl;
string s5(cstr, 3); //将C字符串前3个字符作为字符串s5的初值。
5. cout << s5 << endl;
string s6(5, 'A'); //生成一个字符串,包含5个'A'字符
6. cout << s6 << endl;
string s7(str.begin(), str.begin() + 5); //区间str.begin()和str.begin()+5内的字符作为初值
7. cout << s7 << endl;
return 0;
}
结果;
1.Hello world
2.world
3.wor
4.abcde
5.abc
6.AAAAA
7.Hello
string特性
可用下列函数来获得string的一些特性:
int capacity()const; //返回当前容量(即string中不必增加内存即可存放的元素个数)
int max_size()const; //返回string对象中可存放的最大字符串的长度
int size()const; //返回当前字符串的大小
int length()const; //返回当前字符串的长度
bool empty()const; //当前字符串是否为空
void resize(int len,char c); //把字符串当前大小置为len,多去少补,多出的字符c填充不足的部分
例:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str;
if (str.empty())
1. cout << "str is NULL." << endl;
else
1. cout << "str is not NULL." << endl;
str = str + "abcdefg";
2.cout << "str is " << str << endl;
3.cout << "str's size is " << str.size() << endl;
4.cout << "str's capacity is " << str.capacity() << endl;
5.cout << "str's max size is " << str.max_size() << endl;
6.cout << "str's length is " << str.length() << endl;
str.resize(20, 'c');
7.cout << "str is " << str << endl;
str.resize(5);
8.cout << "str is " << str << endl;
return 0;
}
输出;
1.str is NULL.
2.str is abcdefg
3.str's size is 7
4.str's capacity is 15
5.str's max size is 9223372036854775807
6.str's length is 7
7.str is abcdefgccccccccccccc
8.str is abcde
其他函数
size_type find( const basic_string &str, size_type index ); //返回str在字符串中第一次出现的位置(从index开始查找),如果没找到则返回string::npos
size_type find( const char *str, size_type index ); // 同上
size_type find( const char *str, size_type index, size_type length ); //返回str在字符串中第一次出现的位置(从index开始查找,长度为length),如果没找到就返回string::npos
size_type find( char ch, size_type index ); // 返回字符ch在字符串中第一次出现的位置(从index开始查找),如果没找到就返回string::npos
string &insert(int p,const string &s); //在p位置插入字符串s
string &replace(int p, int n,const char *s); //删除从p开始的n个字符,然后在p处插入串s
string &erase(int p, int n); //删除p开始的n个字符,返回修改后的字符串
string substr(int pos = 0,int n = npos) const; //返回pos开始的n个字符组成的字符串
void swap(string &s2); //交换当前字符串与s2的值
string &append(const char *s); //把字符串s连接到当前字符串结尾
void push_back(char c) //当前字符串尾部加一个字符c
const char *data()const; //返回一个非null终止的c字符数组,data():与c_str()类似,用于string转const char*其中它返回的数组是不以空字符终止,
const char *c_str()const; //返回一个以null终止的c字符串,即c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同,用于string转const char*
类型转换
char-->string
#include <iostream>
#include <string>
#include <cstring> // 包含 strncpy
int main() {
std::string str = "I Love u";
char c[100]; // 确保数组足够大以存储字符串
// 使用 strncpy 进行拷贝,确保最后一个字符为 null terminator
strncpy(c, str.c_str(), sizeof(c) - 1);
c[sizeof(c) - 1] = '\0'; // 确保以 null 结尾
std::cout << c << std::endl; // 打印转换后的 char 数组
return 0;
}
string-->char*
#include <iostream>
#include <string>
int main() {
std::string str = "I Love u";
// 不可修改版本
const char *c = str.c_str();
std::cout << c << std::endl; // 输出字符串
// 可修改版本(注意:这样做是危险的,因为可能会改变 str 内部的字符)
char *modifiable_c = const_cast<char*>(str.c_str());
// 这里可以进行修改,但是请谨慎使用,一般不推荐这样做
// modifiable_c[0] = 'i'; // 这将导致未定义行为,因为在这行操作的字符串是常量的
return 0;
}
总结
- 从
std::string
到char[]
:确保目标数组具有足够的大小,并使用strncpy()
或strcpy()
,但要记得处理 null 终止符。 const char*
转换:使用c_str()
方法进行安全转换,并认识到const_cast
转换是危险的,因为这样操作的内容原本是不可修改的。
C字符串 | string对象 | |
所需的头文件名称 | <string>或<string.h> | <string>或<string.h> |
如何声明 | char name[20]; | string name; |
如何初始化 | char name[20]="nihao"; | string name = "nihao"; |
必须声明字符串长度么? | 是 | 否 |
使用一个null字符么? | 是 | 否 |
怎样实现字符串赋值 | strcpy(name,"John"); | name = "John"; |
其他优点 | 更快 | 更易于使用,优选方案 |
可以赋一个比现有字符更长的字符串么? | 不能 | 可以 |