1.命名空间的using声明:
之前在编写程序时使用std空间中的定义,采用的是
std::cin>>a;
std::cout<<a;
作用域限定符::的含义是右操作数可以在左操作数中找到定义.
C++提供了更为方便的方法使用命名空间的内容,using声明。
Using name_space::name;
后面在使用的时候,可以直接引用名字,而不需要再加上命名空间。
1.1 每个名字都需要一个using声明:
只要使用到std空间中的成员,每个成员都要using声明,每次using声明只能声明一个成员。
using std::cin;
using std::cout;
using std::endl;
1.2 在头文件中必须采用完全限定的命名空间成员的引用:
就是说,在头文件中不要使用using声明,而要使用name_space::name的形式。原因是,头文件会被不同的文件include,如果使用using声明,那么每个文件中都使用了该using声明,然而对某些文件来说有些声明并不是必要的,甚至会造成命名冲突。
2.标准库string类型:
String类型用来处理长度可变的字符串,c++标准库来进行内存的管理和存储的分配,以及提供一些可执行的操作。
String类型包含在string头文件,在std空间中有定义,所以在使用时:
#include <string>
using std::string;
2.1 string类型变量的定义和初始化
String是一个标准库中的类类型,所以它的初始化必须使用构造函数(constructor function),缺省时调用默认构造函数(default constructor function).
几种初始化的方式:
string s1;
string s2(“hello world”);//字符串字面值初始化
string s3(s1);//s1的副本初始化
string s4(10,’a’);//10个字符’a’进行初始化
string s5=s2;//先是调用默认构造函数初始化s5,然后用s2进行赋值
注意字符串字面值与
string
类型是不同的!
下面测试测试字符串字面值“hello world”与string类型的区别:
#include <iostream>
#include <string>
#include <cstdlib>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string s("hello world");
cout << sizeof(s) << endl << sizeof("hello world") << endl;//本人机器的运算结果分别为28和12
getchar();
return 0;
}
2.2 string类型变量的输入输出:
string类型的变量同其他内置类型类似。
2.2.1 cin从非空白字符开始读取,到空白字符读取结束。空白字符包括(空格、回车、制表符等)
cin>>s;
//你输入的内容为 hello world
cout<<s;
//那么标准输出打印的为hello
2.2.2 getline读取一行数据,getline接受两个参数,一个输入流对象,一个string对象,遇到回车时读取结束,getline函数返回值将回车符扔掉
getline(cin,s);
//此时你输入 hello world
cout<<s;
//那么标准输出打印位 hello world
2.2.3 输入未知数目的string对象
While(cin>>s)
{
……
}
While(getline(cin,s))
{
……
}
>> 运算符返回的是左操作数的对象,若返回的输入流对象合法,则继续 while 循环,如返回对象不合法或是读取到文件结尾,则终止循环。
Windows下的文件结束符(end of file) ctrl+z
Linux下的文件结束符 Ctrl+d
2.3 String对象的操作
2.3.1 string的size和empty操作
成员函数size()返回字符串中字符的个数:
int main()
{
<span style="white-space:pre"> </span>string s("hello ");
<span style="white-space:pre"> </span>cout << s.size() << endl;//返回字符串中字符的个数,结果为6,包括空格在内
<span style="white-space:pre"> </span>getchar();
<span style="white-space:pre"> </span>return 0;
}
判断字符串是否为空:
int main()
{
string s;
if (s.size() == 0)
{
cout << "empty" << endl;
}
if (s.empty())
{
cout << "empty" << endl;
}
getchar();
return 0;
}
2.3.2 string::size_type
我们知道,string类类成员函数size()的返回值是一个unsigned类型,但事实上size()的返回值是size_type类型。
int,long等一些整数类型表示的范围是与机器平台有关的,不同的平台表示的范围不同,如果将size()的返回值定义为int类型的话,在进行平台移植的时候可能会出现错误,所以string类类型定义了一些配套类型,这样就能与机器无关了。size_type就是一种配套类型,它与unsigned具有相同的含义,并且可以保证表示任意string对象的长度
size_type是由string定义的,所以在使用时
string::size_type;
2.3.3 string关系操作符
string变量进行比较时,大写字母在小写字母前面,按照字典序进行比较
== <= >= != < >
2.3.4 string对象的赋值
string s1,s2=”hello world”;
s1=s2;
string 对象在进行赋值时会遇到效率的问题,就上例而言,在 s2 赋值给 s1 的过程中,先是 s1 释放内存空间,然后分配给 s1 足够存放 s2 副本内容的内存空间,最后把 s2 中的字符复制到新分配的 s1 内存空间。
2.3.5 string对象相加
string s1(“hello ”);
string s2(“world\n”);
string s3=s1+s2;//s3="hello world\n"
s1+=s2;//s1="hello world\n"
2.3.6 和字符串字面值的连接
int main()
{
string s1("hello");
string s2("world\n");
string s3 = s1 + " " + s2;
cout << s3;
getchar();
return 0;
}
+操作符的左右操作数中必须有一个是string对象
int main()
{
string s1 = "hello";
string s2 = "world";
string s3 = s1 + ",";
// string s4 = "hello" + ",";
string s5 = s1 + "," + "world";
//string s6 = "hello" + "," + s2;
return 0;
}
对于s5:string标准库定义加操作返回一个string对象,这样s1+”,”返回一个string对象,再和”world”进行连接。(类似于输入输出运算符的串联效果)。
显然s6是不合法的。
2.3.7 从string对象获取字符
string对象可以通过下标运算符[]来访问string对象中的单个字符,下标是一个size_type 类型的值,从0开始,最大为size()-1。
int main()
{
string s("hello world");
for (string::size_type index = 0; index != s.size(); ++index)
{
cout << s[index];
}
cout << endl;
getchar();
return 0;
}
注意不要出现下标越界
2.3.8 下标操作可用左值
int main()
{
string s("hello world");
for (string::size_type index = 0; index != s.size(); ++index)
{
s[index] = '*';
cout << s[index];
}
getchar();
return 0;
}
2.3.9 计算下标值
任何可产生的整型表达式都可做下标,但索引的实际数据确是unsigned类型的string::size_type,注意不要越界。
2.4 string对象中字符的处理
一些字符处理函数:
Isalnum(c) // 如果c是字母或数字,则为true
Isalpha(c) //如果c是字母,则为true
Isdigit(c) //如果c是数字,则为true
Iscntrl(c) //如果c是控制字符,则为true //在ascii码中,0-31号及127号为控制字符
Islower(c) //如果是小写字母,则为true
Isupper(c) //如果是大写字母,则为true
Isgraph(c) //如果不是空格,但可打印,则为true
Tolower(c) //如果c不是小写字母,则返回其小写形式,否则返回c
Toupper(c) //如果c不是大写字母,则返回其大写形式,否则返回c
Isxdigit(c) //如果c是16进制数,则返回true
Isspace(c) //如果c是空白字符,则返回true
Ispunct(c) //如果c是标点符号,则为true
Isprint(c) //如果c是可打印的字符,则为true
上述字符处理函数都包含在<cctype>头文件中
int main()
{
/*计算字符串中标点符号的数目*/
string s("!@hello$%hello");
string::size_type count = 0;//最好用这种配套类型,易于跨平台维护
for (string::size_type index = 0; index != s.size(); ++index)
{
if (ispunct(s[index]))
{
++count;
}
}
cout << count << endl;
getchar();
return 0;
}
int main()
{
/*convert s to uppercase*/
string s("hello world\n");
for (string::size_type index = 0; index != s.size(); ++index)
{
s[index] = toupper(s[index]);
}
cout << s;
getchar();
return 0;
}