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

『 C++ 』IO流

文章目录

    • IO流概述
    • iostream 的标准对象
    • C++流和C标准库I/O函数的同步 sync_with_stdio
    • fstream 文件流
      • 文件流的打开标志
      • 二进制读写
      • 二进制读写的浅拷贝问题
      • 文本读写
    • 字符串流
    • 注意


IO流概述

请添加图片描述

流是指数据的有序传输序列,路表示数据从一个地方流向另一个地方的过程,流可以是输入流也可以是输出流,具体取决于数据的流动方向;

  • 输入流

    数据从外部设备(文件,键盘等)流入程序中;

  • 输出流

    数据从程序流向外部设备(如显示器,文件等);

IO流是指用于处理输入输出操作的流,C++中的IO流用于程序与外部环境(用户,文件系统,网络等)之间交换数据的机制;

IO流通过标准库中的一组类和对象实现允许程序员以统一的方式处理不同类型的输入输出设备;

  • <ios>

    <ios>C++中的一个基础头文件,包括了所有输入输出流类的功能;

    其并不是一个具体的六类型,而是提供了一些基类,如ios_baseios(basic_ios);

    是所有输入输出流类的基石;

    <ios>中的类定义了流对象的状态,格式化标志,异常处理等通用功能;

  • <istream>

    该头文件定义了istream类及相关的输入流操作;

    流类型是输入流;

    其作用为istream类用于处理从输入设备(键盘,文件等)读取数据的操作;

    标准输入流对象cin就是istream类的实例;

  • <iostream>

    这个头文件包含了输入输出流的基本类,包括istreamostream;

    流类型是输入输出流,其既包含了输入流也包含了输出流;

    iostream类是一个组合类,继承自istreamostream,可以同时进行输入和输出操作,是一个被棱形继承的类;

    该头文件通常用来处理标准输入输出流的操作(如cincout);

  • <ostream>

    这个头文件定义了处理输出操作的ostream类;

    流类型是输出流;

    ostream类用于将数据输出到输出设备,如屏幕,文件等;

    标准输出流对象cout,标准错误流对象cerr,标准日志流对象clog均为该类的一个实例;

  • <streambuf>

    这个头文件定义了一个streambuf类,这是所有流类的基础缓冲区类;

    流类型是流缓冲区;

    streambufiostream,ifstream,ofstream等类的核心组成部分,负责具体的数据存取操作;

    streambuf通常由更高层次的流类,如istream,ostream使用,但它也可悲用户自定义以实现特殊流的缓冲区操作,如自定义的文件格式或网络流操作;

  • <fstream>

    这个头文件定义了处理文件输入输出的流类,包括ifstream,ofstreamfstream;

    流类型是文件流;

    ifstream是输入文件流类,用于从文件读取数据;

    ofstream是输出文件流类,用于向文件写入数据;

    fstream是读写文件流类,其与iostream相同既具有读也具有写的功能;

  • <sstream>

    这个头文件定义了用于操作字符串的流类,包括istringstream,ostringstreamstringstream;

    流类型是字符串流;

    istringstream用于从字符串读取数据,ostringstream用于将数据写入字符串,stringstream则用于同时进行字符串的读写操作;

这一系列的库用于对标C语言的一系列操作,一个面向过程一个面向对象;

<iostream>主要对标C语言中的printf,scanf等接口,用于处理从输入设备读取数据的操作与处理需要写入至输出设备的数据;

<fstream>对标C语言中的fprintf,fscanf等接口,用于处理向文件内写入与处理从文件中读取的数据;

<sstream>对标C语言中的sprintfsscanf等接口,用于处理字符串输入输出的流类;


iostream 的标准对象

请添加图片描述

C++标准库中iostream头文件定义了一些常用的标准流对象,这些对象在全局范围内可用,用于处理常见的输入输出任务;

  • cin

    标准输入流对象;

    用于从标准输入设备中读取数据(例如键盘);

    cinistream类型的一个实例,支持多种输入操作,可以从输入缓冲区中读取字符,整数,浮点数,字符串等不同类型的数据;

    cin的输入操作是通过提取运算符>>来完成的,这个运算符也被称为 “流提取” ;

    cin提供了一系列的接口(具体参考 istream - C++ Reference (cplusplus.com)):

    但最常用的接口还是operator >>;

    arithmetic types (1)	
    istream& operator>> (bool& val);
    istream& operator>> (short& val);
    istream& operator>> (unsigned short& val);
    istream& operator>> (int& val);
    istream& operator>> (unsigned int& val);
    istream& operator>> (long& val);
    istream& operator>> (unsigned long& val);
    istream& operator>> (long long& val);
    istream& operator>> (unsigned long long& val);
    istream& operator>> (float& val);
    istream& operator>> (double& val);
    istream& operator>> (long double& val);
    istream& operator>> (void*& val);
    stream buffers (2)	
    istream& operator>> (streambuf* sb );
    manipulators (3)	
    istream& operator>> (istream& (*pf)(istream&));
    istream& operator>> (ios& (*pf)(ios&));
    istream& operator>> (ios_base& (*pf)(ios_base&));
    

    这个操作符用于从输入流中提取数据并存储到对应的变量中;

    >>操作符会根据变量的类型自动进行推导,这种操作可以针对多种基本数据类型(内置类型,布尔值,容器等)以及一些特殊的类型(指针,streambuf对象等)进行处理;

    除此之外cin作为istream的实例,还提供了其他的成员函数,如getline(),ignore(),get()等;

    #include <iostream>int main() {int num;char ch;std::cout << "Enter a number: ";std::cin >> num;// 输出读取到的数字std::cout << "You entered the number: " << num << std::endl;// 忽略输入缓冲区中的下一个字符(通常是换行符)std::cin.ignore(1, '\n');std::cout << "Enter a character: ";std::cin.get(ch);std::cout << "You entered the character: " << ch << std::endl;return 0;
    }/*运行结果为:$ ./mytest Enter a number: 42You entered the number: 42Enter a character: aYou entered the character: a*/
    

    在这段代码中使用流提取读取一个整型数据,调用cin.ignore()成员函数忽略一个字符,即\n;

    忽略该字符后该字符不会被下面的cin.get()读取从而程序不会出现不符合需求的现象,否则\n将会被cin.get()读取;

    通常情况下这些函数在使用时查看对应的文档即可;

    • 使用cin进行循环输入

      在一些OJ题目中需要循环进行输入,这种情况下可以使用while(operator>> (std::cin,variable))的方式进行输入;

      int main() {string s1;
      while (cin>>s1) {
      //  while (operator>>(cin, s1)) {cout << s1 << endl;}return 0;
      }/*$ ./mytest hellohelloworldworld^Z[1]+  Stopped                 ./mytest
      */
      

      这里的operator>>其原型为:

      istream& operator>> (istream& is , string& str);
      

      其返回的是istream&的输入流类型引用;

      这里返回的输入流类型引用可以作为判断条件的原因是该类有一个operator bool()的重载,来判断流是否出现错误;

      同时,istream还有一个operator!(),它返回一个布尔值,指示流是否处于错误状态;

      因此当输入成功时,条件为true,循环继续;

      当输入失败时,条件为false,循环终止;

  • cout

    标准输出流对象;

    用于将数据输出至输出设备中(如显示器);

    coutostream类型的一个实例,支持多种输出和写入操作,可以将缓冲区中的整数,浮点数,字符串等不同类型的数据输出(写入)至对应的设备或文件中;

    cout的输出操作是通过插入运算符<<来完成的,这个运算符也被称为 “流插入” ;

    cout提供了一系列的接口(具体参考ostream - C++ Reference (cplusplus.com)):

    cin相同该对象最常用的成员函数为operator <<;

    arithmetic types (1)	
    ostream& operator<< (bool val);
    ostream& operator<< (short val);
    ostream& operator<< (unsigned short val);
    ostream& operator<< (int val);
    ostream& operator<< (unsigned int val);
    ostream& operator<< (long val);
    ostream& operator<< (unsigned long val);
    ostream& operator<< (long long val);
    ostream& operator<< (unsigned long long val);
    ostream& operator<< (float val);
    ostream& operator<< (double val);
    ostream& operator<< (long double val);
    ostream& operator<< (void* val);
    stream buffers (2)	
    ostream& operator<< (streambuf* sb );
    manipulators (3)	
    ostream& operator<< (ostream& (*pf)(ostream&));
    ostream& operator<< (ios& (*pf)(ios&));
    ostream& operator<< (ios_base& (*pf)(ios_base&));
    

    该运算符被称为 “流插入” 运算符,将数据从右侧的表达式插入到左侧的输入流中,即std::cout;

    同样的<<操作符会根据变量的类型自动进行推导,这种操作可以针对多种基本数据类型(内置类型,布尔值,容器等)以及一些重载了operator<<函数的自定义类型;

    coutostream的实例,继承了其原生的一些成员和接口,如刷新缓冲区的内容的flush(),设置浮点数的输出精度的precision()等;

    int main() {std::cout.precision(3);std::cout << 3.14159265 << std::endl;std::cout << "Processing..." << std::flush;// 一些耗时的操作std::cout << "Done!" << std::endl;return 0;
    }
    /*运行结果为:$ ./mytest 3.14Processing...Done!
    */
    

    但通常情况下由于C++C 兼容,编写C++程序时常常使用CC++混编的方式,如在使用精度控制的时候就可以使用C语言的精度控制,若是遇到需要使用这些接口的场合查看文档即可;

    int main() {double d = 3.1415626;printf("d = %.2f\n", d);return 0;
    }
    /*运行结果为:$ ./mytest d = 3.14	
    */
    
  • cerr,clog

    cerr,clogcout一样都是ostream类的一个实例;

    其继承了ostream的各个成员及接口;

    本质上cerrclog分别都是用于打印错误信息与打印日志信息的;

    • cerr

      cerr是不带缓冲的,这意味着当使用cerr打印一个错误信息时该错误信息将被直接打印而不会被存储在缓冲区中,使使用者能够在发生error时第一时间发现对应的错误信息;

      std::cerr << "Error: Something went wrong!" << std::endl;
      
    • clog

      clogcerr不同,默认带缓冲,这意味着当使用clog打印日志信息时日志信息将先被存储在缓冲区中;

      直到缓冲区被写满或是显示调用刷新缓冲区才会将对应的日志信息进行打印;

      std::clog << "Log: Application started" << std::endl;
      

    cerrclog默认都是绑定到标准错误输出流stderr的,因此通常会直接被显示在终端中;

    如果需要也可以调用其成员函数rebuf()将输出重定向到文件或是其他输出设备;

    #include <iostream>
    #include <fstream>int main() {std::ofstream error_file("errors.log"); // 实例化对应的 ofstream 对象std::ofstream log_file("logs.log");std::cerr.rdbuf(error_file.rdbuf()); // 重定向 cerr 到 error_file std::clog.rdbuf(log_file.rdbuf());   // 重定向 clog 到 log_filestd::cerr << "Error: This will go to errors.log" << std::endl;std::clog << "Log: This will go to logs.log" << std::endl;return 0;
    }
    

C++流和C标准库I/O函数的同步 sync_with_stdio

请添加图片描述

sync_with_stdio是C++标准库中用于控制C++流和C标准库I/O函数(如printf,scanf)之间同步行为的函数;

默认情况下C++流(如cin,cout)与C标准库的I/O函数是同步的,意味着每次进行输入或是输出操作时C++流都会刷新其内部缓冲区并与C标准库的I/O缓冲区同步;

这种同步操作是为了确保使用 C++流C标准库 I/O函数时,输出结果的一致,但这种同步操作也会带来一定的性能开销,特别是在需要频繁进行I/O操作的情况下;

可以使用std::ios::sync_with_stdio(false)来关闭 C++流C标准库 I/O函数之间的同步;

关闭同步后,C++流不再与其内部缓冲区和C标准库I/O缓冲区进行同步;

这可以提高I/O操作的效率,特比是对于大量数据的输入和输出;

  • 注意事项

    关闭同步之后,如果在程序中混合使用 C++流C标准库 I/O函数时需要小心,以确保不会出现数据竞争或者输出顺序混乱的问题;

    一旦关闭同步后就无法再重新开启同步;

    int main() {// 关闭 C++ 流和 C 标准库 I/O 函数之间的同步std::ios::sync_with_stdio(false);int age = 25;// 使用 C++ 流输出提示信息std::cout << "请输入您的年龄: ";// 使用 C 标准库函数读取用户输入scanf("%d", &age);// 使用 C++ 流输出用户输入的年龄std::cout << "您的年龄是: " << age << std::endl;return 0;
    }
    /*运行结果为:$ ./mytest 27请输入您的年龄: 您的年龄是: 27
    */
    

    在这个例子中再关闭同步之后先使用std::cout输出提示信息,然后使用std::scanf读取用户输入;

    由于关闭了同步,std::cout的输出缓冲区可能没有被立即刷新到屏幕上;

    因此当程序执行到scanf时用户可能看不到提示信息导致程序行为异常;


fstream 文件流

请添加图片描述

C++提供了一个文件流用于处理文件输入输出的对象,可以从文件中读取数据到程序中或者将程序中的数据写到文件中;

C++标准库提供了三种主要的文件流类:

  • ofstream

    用于向文件写入数据(输出);

  • ifstream

    用于从文件读取数据(输入);

  • fstream

    用于同时进行文件的读写操作;

这三个流类存在对应的函数get/read/>>put/write/<<分别对标C语言的fputc/fwrite/fprintffgetc/fread/fscanf;

提供三种主要的文件流类主要是支持C++的面向对象,即可以支持将类对象中对应的数据写入至文件当中,C语言只能支持将内置类型写入文件内;

流插入和流提取能够更好的支持内置类型和自定义类型;


文件流的打开标志

请添加图片描述

在C++中打开文件时通常使用fstream,ifstreamofstream来打开一个文件流,本质上是定义一个文件流对象;

fstream为例;

文件流对象可以通过open成员函数传入一个const char*字符串或是const string&类型作为文件名打开;

也可以使用构造函数传入一个const char*字符串或是const string&对象作为文件名将文件打开;

/* open 成员函数声名 */
void open (const char* filename,ios_base::openmode mode = ios_base::in | ios_base::out);
void open (const string& filename,ios_base::openmode mode = ios_base::in | ios_base::out);/* 构造函数 */
explicit fstream (const char* filename,ios_base::openmode mode = ios_base::in | ios_base::out);
explicit fstream (const string& filename,ios_base::openmode mode = ios_base::in | ios_base::out);

其中mode表示打开文件时的模式,可以使用一些标志来控制文件流的行为;

这些标志与Linux底层的文件打开接口相似,以二进制标志位的方式标明文件的打开模式,即mode = a | b | c;

常见的标识有:

  • in

    以输入模式打开(读取);

  • out

    以输出模式打开文件(写入),如果文件不存在将创建文件;

    如果文件存在则清空文件内容(除非另有其他标志影响,如app);

  • binary

    以二进制模式打开文件,这意味着数据将以字节流的形式读写,不进行任何格式的转换;

  • ate

    打开文件后,将文件指针定位到文件末尾,但可以在文件的任意位置读写数据;

  • app

    以追加模式打开文件,数据写入时会自动定位到文件末尾,不会覆盖文件中的现有内容;

  • trunc

    如果文件存在,打开时会清空其内容,这是out模式的默认行为;

关闭文件时调用其close成员函数即可;

打开文件后进行读写时同样调用对应的成员函数,writeread;

  • write

    ostream& write (const char* s, streamsize n);
    

    这里的const char*类型并不表示将其作为字符串读取,而是取到该数据的地址后将其以二进制的形式写至文件中,写入大小为streamsize n;

  • read

    istream& read (char* s, streamsize n);
    

    这里的char *类型同样的是以二进制的形式写进并写至对应的内存中,streamsize n表示需要读取文件的大小;


二进制读写

请添加图片描述

二进制读写操作是指以二进制格式从文件中读取或向文件中写入数据;

这种方式直接操作数据的内存表示,更加高效的且没有数据格式的转换,特别适合处理如图像,音频,视频文件等需要保持精度数据格式的文件;

在二进制模式下,数据是以字节流的形式直接读写的,这意味着数据从内存传输到文件或者从文件传输到内存时不会进行任何转换;

但由于不经过任何格式的转换且在内存中数据具有类型而在磁盘/硬盘中数据不存在类型所以写入后无法在磁盘中直接进行查看(数据表示不同);

// Date类的定义,包含友元函数声明和私有成员变量
class Date {// 友元函数声明,允许<<运算符访问Date类的私有成员friend ostream& operator<<(ostream& out, const Date& d);// 友元函数声明,允许>>运算符访问Date类的私有成员friend istream& operator>>(istream& in, Date& d);public:// 构造函数,默认值为1年1月1日Date(int year = 1, int month = 1, int day = 1): year_(year), month_(month), day_(day) {}// bool类型转换函数,当year_为0时返回false,否则返回trueoperator bool() {if (year_ == 0) {return false;}return true;}// 打印操作  void Print(){printf("year= %d ,month= %d ,day= %d\n",year_,month_,day_);}private:// 年份int year_;// 月份int month_;// 日期int day_;
};// 重载<<运算符,用于将Date对象输出到ostream
ostream& operator<<(ostream& out, const Date& d) {out << d.year_ << " - " << d.month_ << " - " << d.day_ << endl;return out;
}// 重载>>运算符,用于从istream输入流中读取Date对象
istream& operator>>(istream& in, Date& d) {in >> d.year_ >> d.month_ >> d.day_;return in;
}// 定义一个结构体testClass,包含成员变量_d1,_d2和_date
struct testClass {char _s1[32];  // 字符数组作为字符串,用于存储某些数据double _d2;  // 双精度浮点类型变量,用于存储某些数据Date _date;  // Date类型变量,用于存储日期
};class BinIO {public:// 构造函数 传入一个 const char* 类型作为文件名BinIO(const char* filename) : filename_(filename) {}// 写void Write(const testClass& wt) {// fstream 实例化 一个对象ofs用于打开文件(以二进制的形式)用于写入操作fstream ofs(filename_, fstream::out | fstream::binary);// 调用write成员函数进行写入ofs.write((const char*)&wt,sizeof(wt));}// 读void Read(testClass& rt) {// fstream 实例化 一个对象ifs用于打开文件(以二进制的形式)用于读取操作fstream ifs(filename_, fstream::in | fstream::binary);// 调用read成员函数进行读取ifs.read((char*)&rt,sizeof(rt));}private:string filename_;  // 文件名
};

这段代码定义了一个用于处理日期的Date类型和一个包含日期及其他数据的结构testClass,并实现了一个用于二进制文件读写的类BinIO;

其中Date类重载了>>运算符和<<运算符使得Date对象可以与流(如coutcin)直接交互;

BinIO用于文件的二进制读写操作;

  • int main() {// 创建一个 testClass 对象 t1,初始化 _d1 为 "hello world",// _d2 为 3.14,_date 为 2001年1月1日testClass t1{"hello world", 3.14, {2001, 1, 1}};// 创建一个 BinIO 对象 b,初始化文件名为 "log.txt"BinIO b("log.txt");// 将 testClass 对象 t1 以二进制形式写入到 "log.txt" 文件中b.Write(t1);return 0;  // 返回 0,表示程序正常结束
    }
    

    这段代码的主要功能是将一个 testClass 对象以二进制形式写入到文件 log.txt 中。

    • 首先使用初始化列表创建了一个 testClass 对象 t1;

      t1_d1 成员变量为字符串 "hello world";

      _d23.14_date 成员为 2001年1月1日;

    • 然后创建了一个 BinIO 对象 b,并将文件名 "log.txt" 传递给它,准备进行文件操作;

    • 接着调用 BinIO 类的 Write 函数,将 t1 的数据以二进制的形式写入到 log.txt 文件中;

    运行程序数据以二进制的方式被写至文件当中;

  • int main() {// 创建另一个 testClass 实例 t2,用于从文件中读取数据testClass t2;// 从文件 "log.bin" 中读取数据到 t2 对象b.Read(t2);// 输出读取到的字符串和 double 类型数据cout << "s1 : " << t2._s1 << " d1 : " << t2._d1 << endl;// 输出读取到的 Date 类型数据cout << "date :" << t2._date << endl;return 0;  
    }
    /*运行结果为:$ ./mytest s1 : hello world d1 : 3.14date :2001 - 1 - 1
    */
    

    在这段代码中创建了另一个testClass类型对象t2用于将文件数据进行读取;

    读取后依次将t2对象中的内容进行打印;


二进制读写的浅拷贝问题

请添加图片描述

在进行二进制读写的时候可能会出现浅拷贝问题导致在对数据进行读取的时候出现内存错误;

其他代码与上述无异;

struct testClass {string _s1;  // 字符数组作为字符串,用于存储某些数据double _d2;  // 双精度浮点类型变量,用于存储某些数据Date _date;  // Date类型变量,用于存储日期
};

假设testClass类中的_s1string类型;

由于string是一个容器,其自行将在内存的堆中开辟空间并进行管理;

在管理过程中该string对象被写入至文件中,被写入至文件内的实际上还有该对象在内存中的空间指针(内容可能并未被拷贝);

当分为两个进程对这个文件进行读写操作时(两次执行,一次进行写一次进行读),在进行读的时候原本的string对象的指针会被读取进新的_s1成员中,但指针所指向的空间已经被销毁从而导致野指针问题;

$ ./mytest 
Segmentation fault

在同一个进程中对文件进行读写操作,可能数据一样会被写入至对应的string对象中但仍会因为野指针出现问题,故在进行二进制的文件读写操作时需要尽可能避免使用容器,否则需要手动将其序列化;


文本读写

请添加图片描述

文本读写与二进制读写不同,文本读写需要将所有的内容转换为字节流才能写入至文件当中;

对于内置类型而言可以使用C++中的to_string将其转换为字符串,在进行读取的时候可以调用C++中的stoi,stod函数将其转换为内置类型;

  • C语言可以使用sprintfsscanf将内置类型转换为自定义类型(尤其是double这种较为复杂的内置类型)

其余代码不变:


// 定义一个结构体testClass,包含成员变量_s1,_d2和_date
struct testClass {string _s1;double _d1;  // 双精度浮点类型变量,用于存储某些数据Date _date;  // Date类型变量,用于存储日期
};class TextIO {public:// 构造函数 传入一个 const char* 类型作为文件名TextIO(const char* filename) : filename_(filename) {}// 写void Write(const testClass& wt) {fstream ofs(filename_, fstream::out | fstream::trunc);// 不同的编译器/平台实现不同// 有些平台可以直接使用默认打开方式if (!ofs) {cerr << "Error opening file for writing!" << endl;return;}ofs << wt._s1 << endl;ofs << wt._d1 << endl;ofs << wt._date << endl;  // 这里调用了 Date 类的 operator << 流插入// 调用的本质是因为 fstream 继承于 iostream// 这里将对应的数据写入至ofs文件流中}// 读void Read(testClass& rt) { 	fstream ifs(filename_);ifs >> rt._s1; // 调用内置类型的流提取ifs >> rt._d1;ifs >> rt._date; // 调用Date重载的流提取}private:string filename_;  // 文件名
};

这段代码其他代码与上文例子相同不变,定义了一个TextIO的文本读写操作,对应的testClass类中的_s1成员的类型换成string类型();

  • 写入操作直接使用流插入<<操作符即可;

    对于内置类型而言会去调用库中的operator<<流插入;

    对于自定义类型而言会去调用在Date中重载的operator<<流插入;

    // 重载<<运算符,用于将Date对象输出到ostream
    ostream& operator<<(ostream& out, const Date& d) {out << d.year_ << " - " << d.month_ << " - " << d.day_ << endl;return out;
    }
    

    其中fstream能够调用ostream的本质原因是fstream是由ostream派生出来的;

    int main() {testClass t1{"hello world", 3.14, {2001, 1, 1}};TextIO b("log.txt");b.Write(t1);return 0;
    }
    

    在这段代码中定义了一个testClass类型对象t1,并创建了一个TextIO类型的对象b类作为文本文件读写操作;

    调用Write成员函数,运行结果文件被写入至log.txt文件中;

    hello world
    3.14
    2001 - 1 - 1
    
  • 对于读操作也是相同,直接调用对应的operator>>流提取即可;

    int main() {testClass t;TextIO b("log.txt");b.Read(t);cout << t._s1 << endl;cout << t._d1 << endl;cout << t._date << endl;return 0;
    }
    

    这里创建一个t用于接收数据,创建一个b对象用于文件的读写;

    读写后打印出t的数据;

    $ ./mytest 
    hello
    0
    1 - 1 - 1
    

    发现文件读取错误;

    这里读取错误的原因有两个;

    • 流插入读取字符串

      在流插入读取字符串时,当字符串与字符串之间存在空格时默认该空格为分隔符;

      此处的_s1类型为string,内容为hello world;

      为避免这个问题可以使用getline单独读取该字符串;

      void Read(testClass& rt) {fstream ifs(filename_);getline(ifs, rt._s1);ifs >> rt._d1 >> rt._date;}
      

      同样的这里的getline传入的是ifs文件流,其类型fstream是IO流中的子类;

      运行结果为:

      $ ./mytest 
      hello world
      3.14
      2001 - 0 - 1
      
    • Date类写入时格式控制不正确

      同样的在进行读取的时候为避免使用流提取的时候不增加过多的操作,在进行文件写入时就需要对格式进行控制;

      Date类在重载operator<<时内容为:

        out << d.year_ << " - " << d.month_ << " - " << d.day_;
      

      同样的在进行流提取时,当出现多个空格时空格会被视作分隔符;

      因此在进行写入的时候就应该进行格式控制;

      ostream& operator<<(ostream& out, const Date& d) {out << d.year_ << " " << d.month_ << " " << d.day_;return out;
      }
      

    修改完上述两处问题后重新进行写入再进行读取;

    $ make # 写入文件
    g++ -o mytest Main.cc -g -Wall -std=c++11
    $ ./mytest # 文件内容正确 
    $ cat log.txt 
    hello world
    3.14
    2001 1 1# 代码修改为读取代码后重新编译
    $ make
    g++ -o mytest Main.cc -g -Wall -std=c++11
    $ ./mytest 
    hello world
    3.14
    2001 1 1
    # 结果正确
    

同样的可以使用getline,其中getline可以自定义分隔符;

istream& getline (istream&  is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);

字符串流

请添加图片描述

C++字符串流stringstream是C++标准库中的一种流类,用于再内存中处理字符串,属于标准库中的sstream;

字符串流允许我们像处理文件流一样处理字符串,它将字符串作为数据源或数据目的地,使得再内存中进行字符串流更加灵活方便;

文件流是以 内存->磁盘 的方式,字符串流则是以 内存->内存 的方式(内存中数据具有类型);

C++中的字符串流主要有三种类型:

  • std::istringstream(输入字符串流)

    用于从字符串中提取数据,相当于字符串作为输入源;

  • std::ostringstream(输出字符串流)

    用于将数据格式化为字符串并存储,相当于将字符串作为输出目的地;

  • std::stringstream(输入/输出字符串流)

    可以同时进行输入和输出操作;

这三种类型实际上是对标C语言中的sprintfsscanf接口,提供了对自定义类型的操作与安全性;

字符串流通常应用于以下几种场景:

  • 字符串的格式化输出

    将不同类型的字符串合并成一个字符串;

  • 字符串的解析

    将字符串分解成不同的部分(如解析逗号分割的值等);

  • 类型转换

    在不同数据类型之间进行安全转换;

假设需要生成一条SQL语句;

利用C语言则是调用sprintf,即:

int main() {char sql[128];char name[24];scanf("%s", &name);sprintf(sql, "select * from t_test name = '%s' ", name);printf("%s\n", sql);return 0;
}
/*运行结果为:$ ./mytest 张三select * from t_test name = '张三' 
*/

此处查找的为内置类型,但若是需要查找自定义类型则需要更复杂的操作;

C++中的字符串流则是可以解决对于自定义类型的操作问题,本质上是重载自定类型的operator<<operator>>,即流插入和流提取操作,而stringstream流则是所有IO流的最底层类,即最后的派生类,可以调用父类封装的成员函数来进行操作;

// Date类的定义,包含友元函数声明和私有成员变量
class Date {// 友元函数声明,允许<<运算符访问Date类的私有成员friend ostream& operator<<(ostream& out, const Date& d);// 友元函数声明,允许>>运算符访问Date类的私有成员friend istream& operator>>(istream& in, Date& d);public:// 构造函数,默认值为1年1月1日Date(int year = 1, int month = 1, int day = 1): year_(year), month_(month), day_(day) {}// bool类型转换函数,当year_为0时返回false,否则返回trueoperator bool() {if (year_ == 0) {return false;}return true;}void Print() {printf("year= %d ,month= %d ,day= %d\n", year_, month_, day_);}private:// 年份int year_;// 月份int month_;// 日期int day_;
};// 重载<<运算符,用于将Date对象输出到ostream
ostream& operator<<(ostream& out, const Date& d) {out << d.year_ << "/" << d.month_ << "/" << d.day_;return out;
}// 重载>>运算符,用于从istream输入流中读取Date对象
istream& operator>>(istream& in, Date& d) {in >> d.year_ >> d.month_ >> d.day_;return in;
}int main() {Date d = {2023, 12, 1};  // 初始化日期对象string sql;stringstream st;st << d;  // 将日期对象格式化为字符串sql += "select * from t_data date = '";sql += st.str();  // 插入格式化后的日期sql += "'";cout << sql << endl;  // 输出SQL语句return 0;
}/*运行结果为:$ ./mytest select * from t_test name = '2023/12/1'
*/

在这段代码中创建了一个Date类,初始化为{2023, 12, 1};

创建了一个string对象sql作为sql语句的存储地;

定义了一个stringstream字符串流st用于自定义类型Date的转换;

当使用流插入时将去调用对应的operator<<将自定义类型中的数据转换为字符串并存储在stringstream字符串流的缓冲区中;

最后使用string类的+=将字符串进行组装;

  • stringstream的序列化和反序列化

    序列化是指将对象的状态转换为一种可存储或传输的格式的过程;

    这样可以将对象保存到文件,数据库,或者通过网络传输;

    序列化之后的数据可以在以后反序列化(也称为反序列化或解串)回原来的对象,从而恢复对象的状态;

    stringstream支持一些较为简单的序列化和反序列化;

    本质上就是调用自定义类型重载的operator<<operator<<,即流插入与流提取;

    但由于stringstream不能很好的支持复杂类型,如标准库的容器等等;

    通常情况下复杂内容的序列化和反序列化可以使用第三方库如Json等;


注意

请添加图片描述

本文中所有代码测试均在Linux-centOS7上进行

相关文章:

『 C++ 』IO流

文章目录 IO流概述iostream 的标准对象C流和C标准库I/O函数的同步 sync_with_stdiofstream 文件流文件流的打开标志二进制读写二进制读写的浅拷贝问题文本读写 字符串流注意 IO流概述 流是指数据的有序传输序列,路表示数据从一个地方流向另一个地方的过程,流可以是输入流也可以…...

enhanced Input Action IA_Look中Action value引脚没有分割结构体引脚的选项

UE5系列文章目录 文章目录 UE5系列文章目录前言二、使用步骤解决办法 前言 据说&#xff0c;unreal engine5中准备废弃“项目设置”中“输入”&#xff0c;操作映射&#xff0c;轴映射。取而代之的是&#xff1a; 使用增强的输入动作&#xff08;Enhanced Input Actions&#…...

C# NetworkStream、ConcurrentDictionary、Socket类、SerialPort、局域网IP 和广域网IP

一、NetworkStream 什么是NetworkStream&#xff1f; NetworkStream 是 .NET Framework 中用于在网络上进行数据传输的流类。它属于System.Net.Sockets 命名空间&#xff0c;并提供了通过网络连接进行读写操作的功能。NetworkStream 主要用于处理从网络套接字&#xff08;Soc…...

大模型--学习范式

1. 自监督学习&#xff08;Self-Supervised Learning&#xff09; 概念&#xff1a;自监督学习是一种特殊形式的监督学习&#xff0c;其中标签不是由人工标注的&#xff0c;而是从输入数据本身自动生成的。模型利用这些自动生成的标签进行训练。自监督学习通常用于预训练阶段&…...

Hadoop-yarn-unauthorized 未授权访问漏洞

一、漏洞描述&#xff1a; Hadoop是一款由Apache基金会推出的分布式系统框架&#xff0c;它通过著名的 MapReduce 算法进行分布式处理&#xff0c;Yarn是Hadoop集群的资源管理系统。YARN提供有默认开放在8088和8090的REST API&#xff08;默认前者&#xff09;允许用户直接通过…...

工作流调度系统(DolphinScheduler、Azkaban、Airflow、Oozie 和 XXL-JOB)

文章目录 1. DolphinScheduler1.1 DolphinScheduler介绍1.2 DolphinScheduler优点 2. Azkaban2.1 Azkaban介绍2.2 Azkaban优点 3. Airflow3.1 Airflow介绍3.1 Airflow优点 4. Oozie4.1 Oozie 介绍4.2 Oozie 优点 5. XXL-JOB5.1 XXL-JOB介绍5.2 XXL-JOB优点 6. 总结 1. DolphinS…...

PyTorch 基础学习(5)- 神经网络

系列文章&#xff1a; PyTorch 基础学习&#xff08;1&#xff09; - 快速入门 PyTorch 基础学习&#xff08;2&#xff09;- 张量 Tensors PyTorch 基础学习&#xff08;3&#xff09; - 张量的数学操作 PyTorch 基础学习&#xff08;4&#xff09;- 张量的类型 PyTorch 基础学…...

CI/CD 自动化:最大限度地提高极狐GitLab 群组的“部署冻结”影响

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门面向中国程序员和企业提供企业级一体化 DevOps 平台&#xff0c;用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规&#xff0c;而且所有的操作都是在一个平台上进行&#xff0c;省事省心省钱。可以一键安装极狐GitL…...

单元训练10:定时器实现秒表功能-数组方式

蓝桥杯 小蜜蜂 单元训练10&#xff1a;定时器实现秒表功能-数组方式 /** Description:* Author: fdzhang* Email: zfdcqq.com* Date: 2024-08-15 21:58:53* LastEditTime: 2024-08-16 19:07:27* LastEditors: fdzhang*/#include "stc15f2k60s2.h"#define LED(x) …...

国外项目管理软件最佳实践:选型与应用

国内外主流的10款国外项目管理软件对比&#xff1a;PingCode、Worktile、Asana、Trello、Monday.com、ClickUp、Wrike、ProofHub、Zoho Projects、Hive。 在寻找适合的国外项目管理软件时&#xff0c;你是否感到不知从何选择&#xff1f;市场上琳琅满目的选项往往令人眼花缭乱&…...

Angular组件概念

Angular 是一个由 Google 维护的开源前端框架&#xff0c;用于构建单页面应用&#xff08;SPA&#xff09;和移动Web应用。Angular 应用由多个组件&#xff08;Components&#xff09;组成&#xff0c;这些组件是 Angular 应用构建块的基本单位。 1. Angular 组件的基本概念 …...

嵌入式人工智能ESP32(4-PWM呼吸灯)

1、PWM基本原理 PWM&#xff08;Pulse-width modulation&#xff09;是脉冲宽度调制的缩写。脉冲宽度调制是一种模拟信号电平数字编码方法。脉冲宽度调制PWM是通过将有效的电信号分散成离散形式从而来降低电信号所传递的平均功率的一种方式。所以根据面积等效法则&#xff0c;…...

继承 (上)【C++】

文章目录 继承的定义继承的语法继承权限和继承到子类后父类成员的访问限定符的变化继承到子类后父类成员的访问限定符的变化 子类继承到了父类的什么&#xff1f;继承中的作用域子类和父类之间的赋值转换子类对象可以直接赋值给父类对象&#xff0c;但是父类对象不能直接赋值给…...

WPF打印控件内容

当我们想打印控件内容时&#xff0c;如一个Grid中的内容&#xff0c;可以用WPF中PrintDialog类的PrintVisual()方法来实现 界面如下&#xff1a; XAML代码如下 <Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width"300"…...

[C++][opencv]基于opencv实现photoshop算法图像剪切

【测试环境】 vs2019 opencv4.8.0 【效果演示】 【核心实现代码】 //图像剪切 //参数&#xff1a;src为源图像&#xff0c; dst为结果图像, rect为剪切区域 //返回值&#xff1a;返回0表示成功&#xff0c;否则返回错误代码 int imageCrop(InputArray src, OutputArray dst,…...

四十、大数据技术之Kafka3.x(3)

&#x1f33b;&#x1f33b; 目录 一、Kafka Broker1.1 Kafka Broker工作流程1.1.1 Zookeeper 存储的Kafka信息1.1.2 Kafka Broker 总体工作流程1.1.3 Broker 重要参数 1.2 生产经验——节点服役和退役1.2.1 服役新节点1.2.2 退役旧节点 1.3 Kafka 副本1.3.1 副本基本信息1.3.2…...

redis——基本命令

什么是Reids&#xff08;REmote Dictionary Server&#xff09; Redis是现在主流的数据库之一&#xff0c;是一个使用ANSI C编写的开源、包含多种数据结构、支持网络的、基于内存、可选持久性的键值对存储数据。 特性 1.速度快 &#xff1a;Redis的数据全部存储瑜内存中。 …...

pytorch实现单层线性回归模型

文章目录 简述代码重构要点 数学模型、运行结果数据构建与分批模型封装运行测试 简述 python使用 数值微分法 求梯度&#xff0c;实现单层线性回归-CSDN博客 python使用 计算图&#xff08;forward与backward&#xff09; 求梯度&#xff0c;实现单层线性回归-CSDN博客 数值微分…...

智能小家电能否利用亚马逊VC搭上跨境快车?——WAYLI威利跨境助力商家

智能小家电行业在全球化背景下&#xff0c;正迎来前所未有的发展机遇。亚马逊为品牌商和制造商提供的一站式服务平台&#xff0c;为智能小家电企业提供了搭乘跨境快车、拓展国际市场的绝佳机会。 首先&#xff0c;亚马逊VC平台能够帮助智能小家电企业简化与亚马逊的合作流程&am…...

顺丰科技25届秋季校园招聘常见问题答疑及校招网申测评笔试题型分析SHL题库Verify测评

Q&#xff1a;顺丰科技2025届校园招聘面向对象是&#xff1f; A&#xff1a;2025届应届毕业生&#xff0c;毕业时间段为2024年10月1日至2025年9月30日&#xff08;不满足以上毕业时间的同学可以关注顺丰科技社会招聘或实习生招聘&#xff09;。 Q&#xff1a;我可以投递几个岗…...

深入理解 Kibana 配置文件:一份详尽的指南

Kibana 是一个强大的数据可视化平台&#xff0c;它允许用户通过 Elasticsearch 轻松地探索和分析数据。Kibana 的配置文件 kibana.yml 是定制和优化 Kibana 行为的关键。在这篇博客中&#xff0c;我们将深入探讨 kibana.yml 文件中的各个配置项&#xff0c;并提供示例说明。 服…...

算法的学习笔记—链表中倒数第 K 个结点(牛客JZ22)

&#x1f600;前言 在编程过程中&#xff0c;链表是一种常见的数据结构&#xff0c;它能够高效地进行插入和删除操作。然而&#xff0c;遍历链表并找到特定节点是一个典型的挑战&#xff0c;尤其是当我们需要找到链表中倒数第 K 个节点时。本文将详细介绍如何使用双指针技术来解…...

聊聊场景及场景测试

在我们进行测试过程中&#xff0c;有一种黑盒测试叫场景测试&#xff0c;我们完全是从用户的角度去理解系统&#xff0c;从而可以挖掘用户的隐含需求。 场景是指用户会使用这个系统来完成预定目标的所有情况的集合。 场景本身也代表了用户的需求&#xff0c;所以我们可以认为…...

Spring Web MVC入门(中)

1. 请求 访问不同的路径, 就是发送不同的请求. 在发送请求时, 可能会带⼀些参数, 所以学习Spring的请求, 主要 是学习如何传递参数到后端以及后端如何接收. 传递参数, 咱们主要是使⽤浏览器和Postman来模拟&#xff1b; 1.1 传递单个参数 接收单个参数&#xff0c;在Spring MV…...

Django后端架构开发:后台管理与会话技术详解

&#x1f31f; Django后端架构开发&#xff1a;后台管理与会话技术详解 &#x1f539; 后台管理&#xff1a;自定义模型类 Django的后台管理系统提供了强大的模型管理功能&#xff0c;你可以通过自定义模型类来控制模型在后台管理界面的显示和操作。自定义模型类通过继承admin…...

挑战Infiniband, 爆改Ethernet(2)

挑战Infiniband, 爆改Ethernet之物理层 前面说过UE为了挑战Infiniband在AI集群和HPC领域的优势地位&#xff0c;计划爆改以太网技术&#xff0c;以适应AI和HPC集群对高性能、可扩展网络的需求。正如UE联盟关于愿景的说明中宣称的&#xff1a;”提供一个完整的架构&#xff0c;通…...

Postman文件上传接口测试

接口介绍 返回示例 测试步骤 1.添加一个新请求&#xff0c;修改请求名&#xff0c;填写URL&#xff0c;选择请求方式 2.将剩下的media参数放在请求body里&#xff0c;选择form-data&#xff0c;选择key右边的类型为file类型&#xff0c;就会出现选择文件的按钮Select Files&a…...

stm32入门学习14-电源控制

有时候我们的程序中有些触发执行条件&#xff0c;有时这些触发频率很少&#xff0c;我们的程序就一直在循环&#xff0c;这样就很浪费电&#xff0c;我们可以通过PWR电源控制来实现低功耗模式&#xff0c;即只有在触发时才执行程序&#xff0c;其余时间可以关闭一些没必要的设备…...

[C++][opencv]基于opencv实现photoshop算法色相和饱和度调整

【测试环境】 vs2019 opencv4.8.0 【效果演示】 【核心实现代码】 HSL.hpp #ifndef OPENCV2_PS_HSL_HPP_ #define OPENCV2_PS_HSL_HPP_#include "opencv2/core.hpp" using namespace cv;namespace cv {enum HSL_COLOR {HSL_ALL,HSL_RED,HSL_YELLOW,HSL_GREEN,HS…...

Github 2024-08-16Java开源项目日报 Top10

根据Github Trendings的统计,今日(2024-08-16统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目10TypeScript项目1Ruby项目1Apache Dubbo: 高性能的Java开源RPC框架 创建周期:4441 天开发语言:Java协议类型:Apache License 2.0St…...

AI学习记录 - torch 的 matmul和dot的关联,也就是点乘和点积的联系

有用大佬们点点赞 1、两个一维向量点积 &#xff0c;求 词A 与 词A 之间的关联度 2、两个词向量之间求关联度&#xff0c;求 : 词A 与 词A 的关联度 5 词A 与 词B 的关联度 11 词B 与 词A 的关联度 11 词B 与 词B 的关联度 25 刚刚好和矩阵乘法符合&#xff1a; 3、什么是…...

leetcode 885. Spiral Matrix III

题目链接 You start at the cell (rStart, cStart) of an rows x cols grid facing east. The northwest corner is at the first row and column in the grid, and the southeast corner is at the last row and column. You will walk in a clockwise spiral shape to visi…...

mysql windows安装与远程连接配置

安装包在主页资源中 一、安装(此安装教程为“mysql-installer-community-5.7.41.0.msi”安装教程&#xff0c;安装到win10环境) 保持默认选项&#xff0c;点击”Next“。 点开第一行加号展开一路展开找到“MySQL Server 5,7,41 - X64”点击选中点击一下中间只想右侧的箭头看到…...

子网掩码是什么以及子网掩码相关计算

子网掩码 (Subnet Mask) 又称网络掩码 (Netmask)&#xff0c;告知主机或路由设备&#xff0c;地址的哪一部分是网络号&#xff0c;包括子网的网络号部分&#xff0c;哪一部分是主机号部分。 子网掩码使用与IP地址相同的编址格式&#xff0c;即32 bit—4个8位组的32位长格式。…...

仿RabbitMQ实现消息队列

前言&#xff1a;本项目是仿照RabbitMQ并基于SpringBoot Mybatis SQLite3实现的消息队列&#xff0c;该项目实现了MQ的核心功能&#xff1a;生产者、消费者、中间人、发布、订阅等。 源码链接&#xff1a;仿Rabbit MQ实现消息队列 目录 前言&#xff1a;本项目是仿照Rabbi…...

SpringBoot教程(二十三) | SpringBoot实现分布式定时任务之xxl-job

SpringBoot教程&#xff08;二十三&#xff09; | SpringBoot实现分布式定时任务之xxl-job 简介一、前置条件&#xff1a;需要搭建调度中心1、先下载调度中心源码2、修改配置文件3、启动项目4、进行访问5、打包部署&#xff08;上正式&#xff09; 二、SpringBoot集成Xxl-Job1.…...

微前端架构的数据持久化策略与实践

微前端架构通过将一个大型前端应用拆分成多个小型、自治的子应用&#xff0c;提升了开发效率和应用的可维护性。然而&#xff0c;数据持久化作为应用的基础需求&#xff0c;在微前端架构中实现起来面临着一些挑战。本文将详细介绍在微前端架构下实现数据持久化的策略、技术和最…...

讲解 狼人杀中的买单双是什么意思

买单双这个概念通常出现在有第三方的板子中 比如 咒狐板子 丘比特板子 咒狐板子 第一天狼队只要推掉预言家 第二天就可以与咒狐协商绑票 推出其他好人 以及丘比特板子 如果拉出一个人狼链 那么如果孤独再连一个狼人 那么 狼队第一天就可以直接派人上去拿警徽&#xff0c;这样…...

回归分析系列5-贝叶斯回归

07贝叶斯回归 7.1 简介 贝叶斯回归将贝叶斯统计的思想应用于回归分析中&#xff0c;通过先验分布和似然函数来推断后验分布。在贝叶斯回归中&#xff0c;模型参数被视为随机变量&#xff0c;并且有自己的分布。通过贝叶斯公式&#xff0c;可以更新这些参数的分布&#xff0c;…...

oracle 数据中lsnrctl 是干啥的

突然发现lsnrctl stop 之后&#xff0c;依然可以启动数据库 就感觉怪怪的&#xff0c;一直以为这个是数据库的守护进程&#xff0c;原来不是。。。。 lsnrctl 是 Oracle 监听器控制实用程序的命令行界面工具&#xff0c;用于管理 Oracle Net 服务监听器。监听器是 Oracle 网络…...

Linux进程--进程地址空间

文章目录 一、进程地址空间1.想当然的内存2.实际的内存1.什么是地址空间2.地址空间和内存3.为什么要区分两种内存 一、进程地址空间 1.想当然的内存 我们在之前的学习中了解过内存的概念&#xff0c;所以变量都要存在内存中我们的程序才能跑起来&#xff0c;那么我们肯定也见…...

C语言传递指针给函数

C 语言允许您传递指针给函数&#xff0c;只需要简单地声明函数参数为指针类型即可。 下面的实例中&#xff0c;我们传递一个无符号的 long 型指针给函数&#xff0c;并在函数内改变这个值 实例1&#xff1a;获取系统的时间值 能接受指针作为参数的函数&#xff0c;也能接受数…...

探索 Kubernetes 持久化存储之 Rook Ceph 初窥门径

在 Kubernetes 生态系统中&#xff0c;持久化存储是支撑业务应用稳定运行的基石&#xff0c;对于维护整个系统的健壮性至关重要。对于选择自主搭建 Kubernetes 集群的运维架构师来说&#xff0c;挑选合适的后端持久化存储解决方案是关键的选型决策。目前&#xff0c;Ceph、Glus…...

今日(2024 年 8 月 13 日)科技新闻

我国成功发射卫星互联网高轨卫星&#xff1a;该卫星的成功发射将助力我国卫星互联网的发展。中国首台中子全散射谱仪运行 3 年成果丰硕&#xff1a;由粤港科技合作打造的多物理谱仪&#xff0c;在中国散裂中子源上运行 3 年来&#xff0c;已完成 300 多项用户实验。该谱仪的关键…...

Unity大场景切换进行异步加载时,如何设计加载进度条,并配置滑动条按照的曲线给定的速率滑动

一、异步加载场景的过程 1、异步加载场景用到的API LoadSceneAsync 2、异步加载的参数说明 &#xff08;1&#xff09;默认参数&#xff1a;SceneManagement.LoadSceneAsync(“SceneName”); AsyncOperation task SceneManager.LoadSceneAsync("SceneName");&a…...

Selenium + Python 自动化测试16(Python基础复习)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 上一篇我们讨论了使用模块化测试的测试模型&#xff0c;从某一程度也反映出熟练掌握一门编程语言的重要性。 为了后续进一步深入学习。本篇文章主要做下Python基础知识的复习。…...

2024新型数字政府综合解决方案(六)

新型数字政府综合解决方案通过融合人工智能、大数据、区块链和云计算技术&#xff0c;构建了一个全方位智能化的政务平台&#xff0c;旨在提升政府服务的效率、透明度和公众参与度。该方案实现了跨部门的数据互联互通与实时更新&#xff0c;利用先进的数据分析和自动化处理技术…...

vscode的C/C++环境配置和调试技巧

目录 1.背景 2.下载编译器 3.配置环境变量 4.安装C/C插件 5.写C语言代码并且编译成功 5.1文件操作 5.2对于两个窗口的解释 5.3C语言编译环境配置 6.创建执行文件 7.编译运行过程 8.写其他的代码的解决方案一 9.写其他的代码的解决方案二 10.同时编译多个.c文件 10…...

Python制作《扫雷》游戏-附源码,轻松看懂,简单易学

今天介绍另一款经典小游戏&#xff0c;扫雷&#xff0c;这个应该是很多人windows电脑里玩的最多的游戏了&#xff0c;乐趣很多&#xff0c;而且还有一定的技术含量在里面&#xff0c;今天我们就来通过python实现这个小游戏。 创建扫雷文件 打开pycharm&#xff0c;创建一个名…...

8路VBO转HDMI2.0支持4K60频率ITE6265芯片方案心得分享

在此之前&#xff0c;有人找到我这边询问能不能将智能电视主板改成机顶盒&#xff0c;将VBO信号转换输出位HDMI进行投屏&#xff0c;具体应用奇奇怪怪&#xff01;但是奈何是甲方大佬。认命照做。从网上也有搜索了解过这类芯片&#xff0c;发现资料很少&#xff0c;所以有了这篇…...