1. 在使用 C/C++ 语言所写的代码中,用双引号括起来的一个或多个字符,称为字符串常量,如 "abcd"
(1)如果没有特殊说明,字符串常量默认是 C 风格的,即系统会在字符串常末尾加上一个空字符 '\0',以表示字符串的结束。
(2)有一种pascal风格的字符串,它在字符串的首部会加上一个表示字符串长度的部分。
2. C 语言中处理字符串常量的几个函数,需要包含头文件 string.h。
(1)strlen,计算字符串的字符个数,不将末尾的空字符计算进去
int strlen(const char *str)
{
assert(strt != NULL);
int len;
while((*str++) != '\0')
{
len++;
}
return len;
}
(2)strcpy,字符串复制,将末尾的空字符也复制进去
char *strcpy(char *dest,const char *src)
{
assert(dest!=NULL && src!=NULL);
char *tmp = dest;
while ((*dest++ = *src++)!='\0')
{
;
}
return tmp;
}
(3)strcmp,比较两个字符串的大小
int strcmp(const char *src, const char *dst)
{
int ret = 0 ;
while(!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst && *src)
++src, ++dst;
if (ret < 0)
ret = -1 ;
else if (ret > 0)
ret = 1 ;
return ret;
}
(4)strcat,将源字符串附在目标字符串末尾(覆盖结尾处的 '\0'),并添加'\0'
char *strcat(char *dest, const char *src)
{
char *address = dest;
assert((dest != NULL) && (src != NULL));
while(*dest)
{
dest++;
}
while((*dest++ = *src++) != '\0')
{
;
}
return address;
}
3. string,C++中对于C 风格字符串的包装类,用于实现安全的 C 风格字符串访问。
string 包含一个字符数组成员变量,用于保存C风格的字符串,如下是 string 类的简单实现。
//
// String 类的头文件
//
#include<iostream>
using namespace std;
class String{
friend ostream& operator<< (ostream&, String&);
public:
// 复制构造函数
// C 风格字符串常量
String(const char* str = NULL);
// 复制构造函数
// String 类型的
String(const String &other);
~String();
// 保存的字符串常量的长度
size_t size();
// 返回 m_data 值
const char *c_str();
// 赋值操作符
String& operator=(const String &other);
// + 操作符
String operator+(const String &other) const;
// == 操作符
bool operator==(const String& other);
// 下标取值
char& operator[](unsigned int);
private:
char *m_data;
};
//
// String 类的实现
//
#include "String.h"
#include <iostream>
String::String(const char* str /* = NULL */)
{
if (!str)
{
m_data = NULL;
}
else
{
m_data = new char[strlen(str) + 1];
strcpy(m_data, str);
}
}
String::String(const String &other)
{
if (0 == other.size())
{
m_data = NULL;
}
else
{
m_data = new char[len + 1];
strcpy(m_data, other.c_str());
}
}
String::~String()
{
delete[] m_data;
}
size_t String::size()
{
return strlen(m_data);
}
const char* String::c_str()
{
return m_data;
}
String& String::operator=(const String &other)
{
if (this != other)
{
// 清理以前的数据
delete[] m_data;
if (0 == other.size())
{
m_data = NULL;
}
else
{
m_data = new char[other.size() + 1];
strcpy(m_data, other.c_str());
}
}
return other;
}
String& String::operator+(const String &other)
{
if (0 == other.size())
{
return *this;
}
else
{
int len = strlen(m_data) + other.size();
char *tmp = new char[len + 1];
strcpy(tmp, m_data);
strcat(tmp, other.c_str());
delete[] m_data;
return other;
}
}
bool String::operator==(const String &other)
{
if (size() != other.size())
{
return false;
}
else
{
if(0 == strcmp(m_data, other.c_str()))
return true;
else
return false;
}
}
char& String::operator[](unsigned int idx)
{
if (idx >= 0 && idx <= size())
{
return m_data[int];
}
else return NULL;
}
ostream& operator<<(ostream& os,String& str)
{
os << str.m_data;
return os;
}
下面是测试程序
#include "String.h"
#include <string>
#include <iostream>
int main(int argc, char **argv)
{
string test_1("abcd");
cout << "&test_1: " << &test_1 << endl;
cout << "test_1.c_str()" << test_1.c_str() << endl;
String test_2("1234");
cout << "test_1.c_str()" << test_2.c_str() << endl;
String test_3("2345");
cout << "test_2.c_str()" << test_3.c_str() << endl;
}
待续.....