当前位置: 首页 > news >正文

建设地情网站的作用乐云seo

建设地情网站的作用,乐云seo,网络公司开发软件,建设网站得目的文章目录 一、C语言的输入输出二、什么是流三、C IO 流1、C 标准 IO 流2、C 文件 IO 流 四、stringstream 介绍 一、C语言的输入输出 在C语言中我们使用最频繁的输入输出方式是 scanf () 与 printf()#xff1a; scanf()#xff1a;从标准输入设备 (键盘) 读取数据#xf… 文章目录 一、C语言的输入输出二、什么是流三、C IO 流1、C 标准 IO 流2、C 文件 IO 流 四、stringstream 介绍 一、C语言的输入输出 在C语言中我们使用最频繁的输入输出方式是 scanf () 与 printf() scanf()从标准输入设备 (键盘) 读取数据并将值存放在变量对应的内存空间中。printf()将指定的文字/字符串输出到标准输出设备 (显示器)。(注意宽度输出和精度输出控制) 实际上C语言借助了相应的缓冲区来进行输入与输出。如下图所示 对输入输出缓冲区的理解 缓冲区的存在可以屏蔽掉低级I/O的实现由于低级I/O的实现依赖操作系统本身内核的实现所以如果能够屏蔽这部分的差异就可以很容易写出可移植的程序。 可以使用这部分的内容实现 “行” 读取的行为对于计算机而言是没有 “行” 这个概念有了这部分我们就可以定义 “行” 的概念然后解析缓冲区的内容返回一个 “行”。 注C语言除了有输入输出接口 scanf 和 printf还有文件操作读写接口 fread/fwrite、fscanf/fprintf以及字符串序列化反序列化接口 sprintf/snprintf/sscanf。 二、什么是流 “流” 即是流动的意思是物质从一处向另一处流动的过程是对一种有序连续且具有方向性的数据 其单位可以是bit/byte/packet 的抽象描述。流的特点是有序连续且具有方向性。 C流是指信息从外部输入设备如键盘向计算机内部如内存输入和从内存向外部输出设备显示器输出的过程。这种输入输出的过程被形象的比喻为 “流”。 为了实现这种流动C定义了I/O标准类库这些每个类都称为流/流类用以完成某方面的功能。 三、C IO 流 C系统实现了一个庞大的 I/O 标准类库其中ios为基类其他类都是直接或间接派生自ios类 1、C 标准 IO 流 C标准库提供了4个全局流对象cin、cout、cerr、clog cin进行标准输入即数据通过键盘输入到程序中。cout进行标准输出即数据从内存流向控制台 (显示器)。cerr进行标准错误的输出。clog进行日志的输出。 从 I/O 标准类库的继承体系图中可以看出cout、cerr、clog 是 ostream 类的三个不同的对象因此这三个对象基本没有区别只是应用场景不同而已。 注在使用这些全局对象流时必须要包含文件并引入std标准命名空间。 在使用 cin/cout 标准输入输出时有如下注意事项 cin为缓冲流。用户从键盘输入的数据会保存在输入缓冲区中当要提取时cin 是从输入缓冲区中取数据如果数据一次输入过多则会暂存在缓冲区中等待被读取。如果数据输出错误则必须在 enter 之前 Backspace 并修改如果回车键按下就无法挽回了只能等待 cin 将输入缓冲区中的数据读取完毕后才要求输入新的数据。 用户输入的数据类型必须与要提取的数据类型一致否则就会出错。但出错只是在流的状态字 state 中将对应位置位 (置1)程序并不会被终止。 和C语言输入规则一样空格和回车都可以作为数据之间的分格符所以多个数据可以在一行输入也可以分行输入。但如果是字符型和字符串则空格无法用 cin 输入因为其会被识别为数据分隔符需要使用 getline 函数。 流插入和流提取运算符的重载 cin 和 cout 之所以可以直接输入和输出内置类型数据是因为标准库已经将所有内置类型的输入和输出全部重载了。 所以对于自定义类型来说如果我们想让其支持 cin/cout 标准输入输出就需要手动重载 和 运算符。需要注意的是自定义类型在重载流插入和流提取运算符时需要先将 operator 和 operator 声明为类的友元函数然后再在类外对函数进行定义至于原因我们在 类和对象下篇 中有详细介绍不清楚的同学可以看一看。 下面我们给出日期类输入输出重载的例子 class Date {//输入输出重载--友元函数friend ostream operator (ostream out, const Date d);friend istream operator (istream in, Date d); public:Date(int year 1, int month 1, int day 1):_year(year), _month(month), _day(day){}private:int _year;int _month;int _day; };istream operator (istream in, Date d) {in d._year d._month d._day;return in; }ostream operator (ostream out, const Date d) {out d._year d._month d._day;return out; }类的上下文转换 C中的类的上下文转换指的是在特定的上下文环境中将对象或表达式隐式地转换为其他类型。这种转换是由编译器自动进行的不需要从代码中显式地进行调用。常见的上下文转换包括 数值类型之间的转换当将一个整数类型赋给一个较小的整数类型、或者将一个浮点类型赋给一个整数类型时编译器会自动转换数据类型。派生类向基类的转换派生类对象可以转换为基类对象的指针或引用这样可以使得派生类对象使用基类的成员函数和成员变量。用户定义的类型转换通过将类定义为带有类型转换运算符的类可以对用户自定义的类型进行转换。 数值类型转换和派生类基类转换我们之前都已经学习过了今天我们来学习用户定义类型转换。下面我通过一个例子来引入。 我们平时在做 OJ 题的时候特别是 ACM 模式的 OJ 题对于IO类型的算法一般都需要循环输入如下 // 单个元素循环输入--元素为内置类型 while (cin a) {// ... }// 多个元素循环输入 while (c a b c) {// ... }// 整行接收--元素为string类型 while (cin str) {// ... }可以看到我们的案例中包含了 string 类型但是我们又发现string 类中重载的流提取运算符 operator 的返回值是 istream 类型的对象。 那么问题来了我们平时只有三种类型的数据能够用来作为逻辑判断 整形非0代表真0代表假。指针类型非空代表真nullptr 代表假。bool 类型true 代表真false 代表假。 而 istream 作为自定义类型的对象如何能够作为逻辑判断的条件呢答案是 istream 类内部重载了 bool 综上由于 istream 类中重载了流提取运算符所以当我们使用 while (cin str)去流中提取对象数据时调用的是 operator该函数返回一个 istream类型的对象同时因为 istream 类中还重载了 bool所以 istream 对象会去调用 operator bool函数operator bool 调用时如果接收流失败或者有结束标志返回 false否则返回 true所以这里自定义类型 istream 的对象可以用作逻辑条件值。 注在需要 bool 类型的地方比如条件判断处编译器会自动调用 operator bool函数将自定义类型转化为 bool 类型。同时operator bool函数被 explicit关键字修饰这是防止隐式地将一个类对象转换成 bool 类型从而在条件判断上造成误解。 我们也可以在我们自己的自定义类中重载 operator和operator bool从而让其支持进行作为逻辑判断值 class Date {friend ostream operator (ostream out, const Date d);friend istream operator (istream in, Date d); public:Date(int year 1, int month 1, int day 1):_year(year), _month(month), _day(day){}operator bool(){//这里的条件是随意写的假设输入_year为0则结束if (_year 0)return false;elsereturn true;}private:int _year;int _month;int _day; };istream operator (istream in, Date d) {in d._year d._month d._day;return in; }ostream operator (ostream out, const Date d) {out d._year d._month d._day;return out; }int main() {//自动识别类型的本质--函数重载//内置类型可以直接使用--因为库里面ostream类型已经实现了//string类型也可以直接使用因为其内部也重载了但其他自定义类型不行int i 1;double j 2.2;string s(abcdef);cout i endl;cout j endl;cout s endl;//自定义类型则需要我们自己重载 和 //如果要让自定义类型对象能够作为逻辑判断值还需要重载bool、int等运算符Date d(2023, 5, 30);cout d endl;while (d){cin d;cout d endl;}return 0; }注意并不是一定要重载 bool 类对象才能作为逻辑条件值重载整形、指针类型都可以因为它们都能够进行逻辑判断。同时operator bool其本质是通过重载将自定义类型转化为内置类型它的使用可以不仅仅局限于用作逻辑条件值也可以用作其他地方。 2、C 文件 IO 流 C 中一共有三个用于文件操作的类 ifstream/ofstream/fstream如下 ifstream – 输入文件流仅用作输入用ofstream – 输出文件流仅用作输出用fstream – 文件流用作输入输出。 这三个类的关系如图 下面我们以 fstream 类为例来解释 C 中面向对象的文件操作其他两个类的使用和 fstream 类的使用基本一样。 构造函数 fstream 支持无参构造和带参构造不支持拷贝构造支持移动构造 无参构造创建一个未与任何文件关联的流对象即不会打开任何文件。当使用默认构造函数创建 fstream 对象时我们需要使用 open 函数来让对象与一个文件相关联。 带参构造需要指定要打开的文件名以及文件的打开方式如果要以多种方式打开则需要使用 | 运算符。C 文件的打开方式如下其中 in/out 表示该对象对文件进行读/写操作binary/ate/app/trunc 分别表示向文件中读取/写入数据的格式 – 二进制读取或写入/文件尾写入/追加写入/写入前清空文件内容。 特别注意fstream 默认情况下以只读形式打开文件以文本格式向文件中读取和写入数据。同时文件对象在析构时会自动调用 close 成员函数关闭文件当然我们也可以手动调用 close 来关闭文件。 文件操作相关成员函数 我们可以使用流提取和流插入运算符对文件进行读写操作或使用成员函数进行读写。 需要注意的是虽然 ifstream/ofstream/fstream 类中提供了非常丰富的成员函数来让我们对文件进行操作 但是这些接口在实际开发中其实用的最多的还是 operator和operator其他接口都用的很少包括 read 和 write 接口。这是因为operator和operator使用起来非常方便通过这两个接口向文件中读取和写入数据就和我们向标准输入输出中写入读出数据一样 – cin 从文件/标准输入读取数据cout 向文件/标准输出写入数据 (其实本质上标准输入输出也是文件或者是流)。 下面是 C 面向对象文件操作的一个示例 struct ServerInfo {char _address[32];int _port;Date _date; };struct ConfigManager { public:ConfigManager(const char* filename):_filename(filename){}void WriteBin(const ServerInfo info){ofstream ofs(_filename, ios_base::out | ios_base::binary);ofs.write((const char*)info, sizeof(info));}void ReadBin(ServerInfo info){ifstream ifs(_filename, ios_base::in | ios_base::binary);ifs.read((char*)info, sizeof(info));}//C文件流的优势就是可以对内置类型和自定义类型都使用一样的方式去流插入和流提取数据//但是需要自定义类型Date重载了 和 void WriteText(const ServerInfo info){//默认以文本格式向文件中读取和写入数据ofstream ofs(_filename);//这里可以调用成员函数write但是运算符更方便ofs info._address info._port info._date;}void ReadText(ServerInfo info){ifstream ifs(_filename);ifs info._address info._port info._date;}private:string _filename; // 配置文件 };int main() {ServerInfo winfo { 192.0.0.1, 80, { 2023, 5, 30 } };// 二进制读写ConfigManager cf_bin(test.bin);cf_bin.WriteBin(winfo);ServerInfo rbinfo;cf_bin.ReadBin(rbinfo);cout rbinfo._address rbinfo._port rbinfo._date endl;// 文本读写ConfigManager cf_text(test.text);cf_text.WriteText(winfo);ServerInfo rtinfo;cf_text.ReadText(rtinfo);cout rtinfo._address rtinfo._port rtinfo._date endl;return 0; }注意如果文件是以二进制格式打开的则不能直接向文件中写入 string 对象因为 string 是自定义类型其中除了有 char* _str字符数组之外还有很多其他成员变量和成员函数若直接将其写入到文件中那么写入的数据就是该对象所占用的内存空间即对象中成员变量和成员函数的地址而不是字符串本身的内容即 _str 变量指向的堆空间中的字符数组。这样在读取文件时就无法正确地获取原始字符串数据 (下次进行读取时该对象可能已经被销毁再通过旧对象中成员变量的地址去访问堆上的字符数组会造成野指针访问)。 但以文本格式打开的文件可以直接向其中写入 string 对象因为在文本文件中数据是按照字符编码的形式存储的即将单个字符转换成相应的数字形式后再存储到文件中即将堆空间中字符数组对应的 ASCII 值写入到文件。因此字符串数据可以直接以文本形式写入到文件中并在读取时直接通过 运算符等操作进行读取。 四、stringstream 介绍 在C语言中如果想要将内置类型/结构体类型的数据转化为字符串格式通常是使用 sprintf/snprintf 函数但是这两个函数在使用时需要先给出保存结果的空间而空间要给多大是不好界定的。并且当转化格式不匹配时还可能会得到错误的结果甚至程序直接崩溃。 C 提供了 stringstream 类来解决这个问题。stringstream 包含在 sstream 头文件中该头文件下主要有三个类istringstream、ostringstream 和 stringstream分别用来进行流的输入、输出和输入输出操作本文主要介绍 stringstream。 stringstream 主要有以下用途 将数值类型数据格式化为字符串。 #includesstream int main() {int a 12345678;string sa;// 将一个整形变量转化为字符串存储到string类对象中stringstream s;s a;s sa;cout sa endl;// clear()// 注意多次转换时必须使用clear将上次转换状态清空掉// stringstreams在转换结尾时(即最后一个转换后),会将其内部状态设置为badbit// 因此下一次转换是必须调用clear()将状态重置为goodbit才可以转换// 但是clear()不会将stringstreams底层字符串清空掉// s.str();// 将stringstream底层管理string对象设置成,// 否则多次转换时会将结果全部累积在底层string对象中s.str();s.clear(); // 清空s, 不清空会转化失败double d 12.34;s d;s sa;string sValue;sValue s.str(); // str()方法返回stringsteam中管理的string类型cout sValue endl;return 0; }字符串拼接。 int main() {stringstream sstream;// 将多个字符串放入 sstream 中sstream first string,;sstream second string;cout strResult is: sstream.str() endl;// 清空 sstreamsstream.str();sstream third string;cout After clear, strResult is: sstream.str() endl;return 0; }序列化和反序列化结构数据。 struct ChatInfo {string _name; // 名字int _id; // idDate _date; // 时间string _msg; // 聊天信息 };int main() {// 结构信息序列化为字符串ChatInfo winfo { 张三, 135246, { 2022, 4, 10 }, 晚上一起看电影吧 };//将结构数据序列化到stringstream对象中ostringstream oss;oss winfo._name winfo._id winfo._date winfo._msg;//将stringstream中的字符串反序列化到string对象中或直接输出string str oss.str();cout str endl endl;// 我们通过网络这个字符串发送给对象实际开发中信息相对更复杂// 一般会选用Json、xml等方式进行更好的支持// 字符串解析成结构信息ChatInfo rInfo;istringstream iss(str);iss rInfo._name rInfo._id rInfo._date rInfo._msg;cout ------------------------------------------------------- endl;cout 姓名 rInfo._name ( rInfo._id ) ;cout rInfo._date endl;cout rInfo._name : rInfo._msg endl;cout ------------------------------------------------------- endl;return 0; }需要注意的是 序列化和反序列化操作在网络中非常重要它用于在不同的计算机之间传输数据。比如当客户端需要向服务器发送一个请求时它需要将请求数据序列化为字节流并通过网络传输到服务器。在服务器端接收到请求后需要对接收到的字节流进行反序列化操作获得原始的请求数据从而能够获取客户端请求的具体信息并做出相应的响应。C 提供的 stringstream 虽然可以完成序列化与反序列化操作但是它只适用于小型对象的序列化和反序列化操作。如果需要处理大量的数据或者需要进行高性能的序列化和反序列化操作则需要更加专业化的序列化库比如 Json 和 protobuf这些我们将在 Linux 网络编程部分进行学习。 stringstream 有如下注意事项 stringstream 实际是在其底层维护了一个 string 类型的对象用来保存结果。多次进行数据类型转化时一定要用 clear() 来清空才能正确转化但 clear() 不会将 stringstream 底层的 string 对象清空。可以使用 s. str(“”) 方法将底层 string 对象设置为 “空字符串”。可以使用 s.str() 让 stringstream 返回其底层的 string 对象。stringstream 使用 string 类对象代替字符数组可以避免缓冲区溢出的危险 (自动扩容)而且其会对参数类型进行推演不需要格式化控制也不会出现格式化失败的风险因此使用更加方便和安全。
http://www.dnsts.com.cn/news/90858.html

相关文章:

  • 专业网站是指什么淘宝官网首页电脑版手机登录
  • 山西省建设银行网站上海网站建设小程序开发
  • 做海岛旅游预定网站的网页链接生成二维码
  • 姜堰 万邦建设集团网站百度人气榜
  • 甘肃网站建设专业定制如何做网站搜索优化
  • 第一站商城网站建设技巧亅金手指排名27
  • o2o网站建设服务上海网站建设公司 珍岛
  • 合肥seo网站建设广告创意设计方案
  • 深圳企业模板建站镇江网站建设联系思创
  • 个体工商户 网站建设创建电子商务网站的步骤
  • 模板建站价格苏州软件开发培训机构
  • 国际网站如何推做推广做网站开源
  • 无锡的网站建设公司做网站需要哪些资料
  • 网站开发工具 n在网上做企业网站怎么做
  • 西安做企业网站网站空间商排名
  • 国外免费logo设计网站canvas做的网站
  • 网站及数据库怎么做后门wordpress站点logo多大合适
  • 汉阳区建设局网站网站制作关键字排名
  • 怎么把做的网站上传到网络WordPress网站封装app教程
  • 企业手机网站建设价位怎样才能建设网站
  • 销售网站建设方案中国十大网络科技公司排名
  • 网站系统建设合同范本电子商务网站建设实验报告心得
  • 广州北京网站建设成都网站建设yingrihe
  • 社保个人网站wordpress附件上传云
  • 南通快速建设网站服务做淘宝联盟网站
  • 不能进入建设银行网站网站开发应注意哪些问题
  • 做农业种子的网站滑板网页网站设计
  • 美妆网站开发背景新乡做新网站
  • 织梦手机网站免费模板seo排名优化方式
  • 网站空间关闭了怎么办广州新塘做网站