IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 易错知识点记录(含常用函数) -> 正文阅读

[C++知识库]C++ 易错知识点记录(含常用函数)

1. C风格字符串处理函数

strlen()? //计算字符串的长度

strcpy()? //将字符串复制到字符数组中

strncpy()

strcat()? //将字符串附加到字符数组末尾

strncat()

(1)头文件 #include <cstring>

(2)strlen()函数

????????strlen()函数返回的是存储在数组中字符串的长度,而不是数组本身的长度。且只计算可见的字符,不把空字符'\0'计算在内。如果cosmic是字符串,则存储此字符串的数组长度不能小于strlen(cosmic)+1。

(3)strcpy()函数和strncpy()函数

char food[20] = "carrots";
strcpy(food, "flan");

strncpy(food, "a picnic basket filled with many goodies", 19);
food[19] = '\0';

????????strcpy()函数会在最后自动添加'\0'。strncpy()接收第3个参数——要复制的最大字符数。注意,如果该函数在到达字符串结尾之前,目标内存已经用完,则它不会添加空字符,因此需要手动添加。上例中,如果该字符串少于19个字符,则strncpy()将在复制完该字符串之后加上空字符,以标记该字符串的结尾。

????????注意,应使用strcpy()或者strncpy(),而不是赋值运算符来将字符串赋给数组。

2. 字符串的IO

????????cin使用空白(空格、制表符和换行符)来确定字符串的结束位置,这意味着cin在获取字符数组输入时只读取一个单词,将其放到数组中,并自动在结尾添加空字符

????????istream中的类(如cin)提供了一些面向行的类成员函数:getline()和get()。这俩函数都读取一行输入,直到到达换行符。区别是,getline()将丢弃换行符,而get()将换行符保留在输入序列中

(1)面向行的输入:getline()。调用方法:cin.getline()

? ? ? ? 1)该函数包含两个参数,第一个参数用来存储输入行的数组的名称,第二个参数指出要读取的字符数,如果此参数为20,则最多读取19个字符,余下的空间用于存储在结尾自动添加的空字符getline()成员函数在读取指定数目的字符遇到换行符时停止读取。

? ? ? ? 2)该函数有三个参数的版本

? ? ? ? 3)如果处理string对象,则调用方法为:getline(cin, str);

(2)面向行的输入:get()

? ? ? ? get()的一种重载与getline()类似,接收的参数相同,解释参数的方式也相同,并且都读取到行尾,但get()并不再读取并丢弃换行符,而是将其留在输入队列中。

? ? ? ? get()的第二种重载:使用不带任何参数的cin.get()调用可读取下一个字符(即使时换行符)。注意,get()函数在调用后,会将换行符留在输入队列里。注意采用下面的调用序列:

cin.get(name, ArSize);

cin.get();

cin.get(dessert, ArSize);

????????另一种使用get()的方式是将两个类成员函数拼接起来:

cin.get(name, ArSize).get();

????????这是由于cin.get(name, ArSize)返回一个cin对象,该对象随后被用来调用get()函数。同样,下面的语句用来将输入中连续的两行分别读入数组name1和name2中,其效果与两次调用cin.getline()相同:

cin.getline(name1, ArSize).getline(name2, ArSize);

? ? ? ? 注意:不接受任何参数的cin.get()成员函数返回输入中的下一个字符。因此可以这样使用:ch = cin.get()。而cin.get(ch)返回一个对象,而不是读取的字符??

(3)文件尾条件

????????如果输入来自于文件,则可以使用一种功能更加强大的技术——检测文件尾(EOF)。C++输入工具和操作系统协同工作,来检测文件尾并将这种信息告知程序。很多操作系统都允许通过键盘来模拟文件尾条件。

// textin4.cpp -- reading chars with cin.get()
#include <iostream>
 
int main()
{
	using namespace std;
	int ch;  //由于EOF表示的不是有效字符编码,因此可能不与char类型兼容
	int count = 0;
 
	while ((ch = cin.get()) != EOF)  //EOF表示没有字符
	{
		cout.put(char(ch));
		++count;
	}
	cout << endl << count << " characters read\n";
 
	return 0;
}

? ? ? ?方法cin.get(char)返回一个cin对象,istream类提供了一个可以将istream对象(如cin)转换为bool值的函数,当cin出现在需要bool值的地方(如while循环的测试条件中)时,该转换函数被调用。如果最后一次读取成功了,则转换得到的bool值为true;否则为false。因此上述判断条件也可以使用:

while(cin.get(ch))
{
...
}

????????get()的使用使得错误检查更简单些。比如如何知道停止读取的原因是由于已经读取了整行而不是由于数组已填满呢?假如使用get()读取,查看下一个输入字符,如果是换行符则说明已经读取了整行,否则说明该行中还有其他输入。

? ? ? ? get()的主要用途是能够将stdio.h的getchar()和putchar()函数转换为iostream的cin.get()和cout.put()方法。

cin.get(ch)和cin.get()对比
属性cin.get(ch)ch = cin.get()
传递输入字符的方式赋给参数ch将函数返回值赋给ch
用于字符输入时函数的返回值istream对象(执行bool转换后为true)int类型的字符编码
到达EOF时函数的返回值istream对象(执行bool转换后为false)EOF

(4)空行和其他问题

????????当getline()或get()读取空行时,当前的做法是,当get()读取空行后将设置失效位(failbit),这意味着接下来的输入将被阻断,但可以用命令cin.clear();来恢复输入。

????????如果输入行包含的字符数比指定的多,则getline()和get()将把余下的字符留在输入队列中,而getline()还会设置失效位,并关闭后面的输入。

(5)混合输入字符串和数字

// numstr.cpp -- following number input with line input
#include <iostream>
int main()
{
	using namespace std;
	cout << "What year was your house built? \n";
	int year;
	cin >> year;
	cin.get(); // 或者使用cin.get(ch);
	// 或者使用拼接:(cin >> year).get();  目的都是为了将输入数字后的换行符消掉
	cout << "What is its street address? \n";
	char address[80];
	cin.getline(address, 80);
	cout << "Year built: " << year << endl;
	cout << "Address: " << address << endl;
	cout << "Done!\n";
 
	return 0;
}

(6)指针和字符串

1)下述代码:

char flower[10] = "rose";
cout << flower << "s are red\n";

????????数组名是第一个元素的地址,因此cout语句中的flower是包含字符r的char元素的地址。cout对象认为char的地址是字符串的地址,因此它打印该地址处的字符,然后继续打印后面的字符,直到遇到空字符为止。

????????在C++中,用引号括起的字符串像数组名一样,也是第一个元素的地址。注意:在cout和多数C++表达式中,char数组名、char指针以及用引号括起的字符串常量都被解释为字符串第一个字符的地址。因此可用cout直接打印。

// 4.20 ptrstr.cpp -- using pointers to strings
#include <iostream>
#include <cstring>
using namespace std;

int main() {
	char animal[20] = "bear";  //可以直接用常量字符串给char数组赋值
	const char* bird = "wren"; //"wren"是指向第一个字符w的地址,因此bird也指向第一个字符w,
	                           //注意字符串字面值是常量,因此使用const
	char* ps;                  //未初始化的char指针

	cout << animal << " and "; //直接将char数组名作为给cout的参数
	cout << bird << "\n";      //直接将指向char的指针作为给cout的参数
//  cout << ps << "\n";        //由于ps没有初始值,会导致出错

	cout << "Enter a kind of animal: ";
	cin >> animal;             //由cin向char数组赋值时,会自动读取字符,并自动在最后加‘\0’
//  cin >> ps;                 //非常可怕,野指针没有指向一个预分配的内存,向其中写入东西可能覆盖重要文件
	                           //在将字符串读入程序时,应使用已经分配的内存地址。该地址可以是数组名,也可以是使用new初始化过的指针

	ps = animal;
	cout << ps << "!\n";
	cout << "Before using strcpy():\n";
	cout << animal << " at " << (int*)animal << endl;  //打印地址
	cout << ps << " at " << (int*)ps << endl;

	ps = new char[strlen(animal) + 1];
	strcpy(ps, animal);
	cout << "After using strcpy():\n";
	cout << animal << " at " << (int*)animal << endl;
	cout << ps << " at " << (int*)ps << endl;
	delete[] ps;               //使用new分配内存后,一定记得释放内存,避免内存泄露

    return 0;
}

3.? const修饰问题

(1)将char**看作(char*)*,然后找const修饰的对象。

(2)明确const修饰的对象,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向常量;如果const位于星号的右侧,则const就是修饰指针本身,即指针本身是常量,不能修改为指向其他变量。

(3)C++中,对于指针ptr1和ptr2,

char* ptr1;

const char*ptr2 = ptr1;?

//合法: ptr1是指向char类型的指针;ptr2是指向const char类型的指针

char**ptr1;

const char** ptr2 = ptr1;

//不合法:ptr1是指向(char*)类型的指针,ptr2是指向((const char)*)类型的指针

char**ptr1;

char const** ptr2 = ptr1;

//不合法:与上等价

char** ptr1;

char* const* p2 = p1;

//合法:ptr1是指向(char*)类型的指针,ptr2是指向“带有const限定”的(char*)类型的指针

非const赋值给const只能一层。

声明记忆:

const char* p;? ? ?//*p是const,p可变

const (char*) p;? ?//p是const,*p可变

char* const p;? ? ? //p是const,*p可变

const char* const p;? //p和*p都是const

char const* p;? ? ? ?//*p是const,p可变

(char*) const p;? ? ?//p是const,*p可变

char* const p;? ? ? ? //p是const,*p可变

char const* const p;? //p和*p都是const

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:25:18  更:2021-08-12 16:26:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 8:04:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码