C/C++开发,无可避免的IO输入/输出(篇三).字符串流(内存流)IO处理
目录
一、字符串流
1.1 字符串流继承体系
1.2 字符串流本质-类模板std::basic_stringstream
1.3 字符串流缓冲-std::stringbuf
1.4 stringbuf与序列缓冲
1.5 字符串流的打开模式
二、字符串流的运用
2.1 格式转换是其拿手好戏
2.2 字符串流仅提供移动赋值
2.3 std::basic_stringstream不仅仅是字符串支持
2.4 字符串流在信息拼接上也有独到之处
三、演示源代码补充
一、字符串流
1.1 字符串流继承体系
c++的设备抽象层IO流(iostream/ostream/istream)派生了两个体系,一个是文件流(fstream/ofstream/ifstream),另一个则是字符串流(即内存流,stringstream/ostringstream/istringstream,字符串输入输出、字符串输出、字符串输入)。另外,字符串流的每个类都有一个对应的宽字符集版本。一般情况下使用stringstream就足够,因为字符串要频繁的涉及到输入输出。
因此本专栏本专题前面讲述的设备抽象层IO流所具有的能力,例如打开标志、流状态管理、缓冲区管理、寻位、格式化、回调等(这些就不再本文展开),字符串流同样具备,并在应用过程中发现和抽象层IO流、文件流很大一部分功能是重合的,那么为何还需要一个字符串流呢,为何 字符串类(string)功能不能胜任其应用呢。
stringstream类既然命名为字符串流,那么它最大的特点就是"流"特性了,开发者可以向“流水”一样向stringstream对象传递数据。
#include <iostream>
#include <sstream>void stringstream_first_test(void)
{std::stringstream ss;ss << "hello ";ss << "world!";ss << std::endl;ss << "I'm c++ developer!";std::cout << ss.str() << std::endl;
}
//out log
D:\workForMy\workspace\io_c++_test3>test.exe
hello world!
I'm c++ developer!
1.2 字符串流本质-类模板std::basic_stringstream
类似于文本流,stringstream类的本质实现来自于类模板std::basic_stringstream的特化,即
namespace std {template<class CharT, class Traits = char_traits<CharT>,class Allocator = allocator<CharT>>class basic_stringbuf;using stringbuf = basic_stringbuf<char>;using wstringbuf = basic_stringbuf<wchar_t>;template<class CharT, class Traits = char_traits<CharT>,class Allocator = allocator<CharT>>class basic_istringstream;using istringstream = basic_istringstream<char>;using wistringstream = basic_istringstream<wchar_t>;template<class CharT, class Traits = char_traits<CharT>,class Allocator = allocator<CharT>>class basic_ostringstream;using ostringstream = basic_ostringstream<char>;using wostringstream = basic_ostringstream<wchar_t>;template<class CharT, class Traits = char_traits<CharT>,class Allocator = allocator<CharT>>class basic_stringstream;using stringstream = basic_stringstream<char>;using wstringstream = basic_stringstream<wchar_t>;
};
std::basic_stringstream是一个类模板,实现基于字符串的流上的输入与输出操作。将前面的例子替换为std::basic_stringstream<char>对象测试看看:
void basic_stringstream_test(void)
{std::basic_stringstream<char> ss;ss << "hello ";ss << "world!";ss << std::endl;ss << "I'm c++ developer!";std::cout << ss.str() << std::endl;
}
//main.cppstringstream_first_test();basic_stringstream_test();
//out log 是一致的
D:\workForMy\workspace\io_c++_test3>test.exe
hello world!
I'm c++ developer!
hello world!
I'm c++ developer!
1.3 字符串流缓冲-std::stringbuf
std::basic_stringstream它等效地存储一个 std::basic_string(basic_stringstream<char>) 的实例,并在其上进行输入与输出操作。该类实际上在低层包装 std::basic_stringbuf 的原生字符串设备到 std::basic_iostream 的高层接口中。提供到独有 std::basic_stringbuf 成员的完整接口,即字符串流的缓冲区及相关处理功能由std::stringbuf(std::basic_stringbuf<char>)类来完成的。
//定义于头文件 <sstream>
template< class CharT,class Traits = std::char_traits<CharT>,class Allocator = std::allocator<CharT>
> class basic_stringstream; 类型 定义
stringstream basic_stringstream<char>
wstringstream basic_stringstream<wchar_t> 成员类型 定义
char_type CharT
traits_type Traits ;若 Traits::char_type 不是 CharT 则程序非良构。
int_type Traits::int_type
pos_type Traits::pos_type
off_type Traits::off_type
allocator_type Allocator 成员函数
(构造函数) 构造字符串流(公开成员函数)
operator= (C++11)移动字符串流(公开成员函数)
swap (C++11)交换两个字符串流(公开成员函数)
rdbuf 返回底层未处理的字符串设备对象(公开成员函数) 字符串操作
str 获取或设置底层字符串设备对象的内容(公开成员函数)
view (C++20)获得底层字符串设备的内容上的视图(公开成员函数) 非成员函数
std::swap(std::basic_istringstream) (C++11)特化 std::swap 算法(函数模板) //相关父类的成员和设备抽象层IO流、文件流是一致的这里就不详细给出,可以参看前面博文
【1】***继承自 std::basic_istream省略
【2】***继承自 std::basic_ostream省略
【3】***继承自 std::basic_ios省略
【4】***继承自 std::ios_base省略
std::basic_stringbuf 是关联字符序列为内存常驻的任意字符序列的 std::basic_streambuf 。能从 std::basic_string 的实例初始化它,或将它做成该类的实例。
//定义于头文件 <sstream>
template< class CharT,class Traits = std::char_traits<CharT>,class Allocator = std::allocator<CharT>
> class basic_stringbuf : public std::basic_streambuf<CharT, Traits>
std::basic_stringbuf 的典型实现保有一个 std::basic_string 类型对象,或等价的可伸缩序列容器作为数据成员,并将它同时用作受控制字符序列(为 std::basic_streambuf 的六个指针所指向的数组)和关联字符序列(所有输入操作的字符源和输出操作的目标)。另外,典型的实现保有一个 std::ios_base::openmode 类型的数据成员,以指示流的状态(只读、只写、读写、尾端写等)。若 overflow() 使用过分配策略,则可存储另外的高水位指针,以跟踪最后初始化的字符。 (C++11 起)。
公开成员函数
(构造函数) 构造一个 basic_stringbuf 对象(公开成员函数)
operator= (C++11)赋值 basic_stringbuf 对象(公开成员函数)
swap (C++11)交换二个 basic_stringbuf 对象(公开成员函数)
(析构函数) [虚](隐式声明)析构 basic_stringbuf 对象和其所保有的 string(虚公开成员函数)
str 替换或获得关联字符串的副本(公开成员函数)
get_allocator (C++20)获得与内部 basic_string 关联的分配器的副本(公开成员函数)
view (C++20) 获得底层字符序列上的视图(公开成员函数) 受保护成员函数
underflow [虚] 返回输入序列中可用的下一字符(虚受保护成员函数)
pbackfail [虚] 回放字符到输出序列中(虚受保护成员函数)
overflow [虚] 后附字符到输出序列(虚受保护成员函数)
setbuf [虚] 试图以数组替换受控字符序列(虚受保护成员函数)
seekoff [虚] 用相对寻址,重定位输入序列、输出序列或两者中的下一位置指针(虚受保护成员函数)
seekpos [虚] 用绝对寻址,重定位输入序列、输出序列或两者中的下一位置指针(虚受保护成员函数) 非成员函数
std::swap(std::basic_stringbuf) (C++11)特化std::swap算法(函数模板) //父类streambuf这里就不详细给出,可以参看前面博文
【1】***继承自 std::basic_streambuf
1.4 stringbuf与序列缓冲
stringbuf在输入输出序列上的操作大多是受保护的虚函数,开发者可以继承stringbuf类,然后在派生类重载这些函数以实现与项目开发切合的额外功能。如果stringstream对象想直接调用这些已经实现的这些虚实现,例如setbuf,需要通过rdbuf函数先获得stringbuf对象指针,才能进行调用。
void basic_stringstream_test1(void)
{std::basic_stringstream<char> ss;char c[256] = {0};ss.rdbuf()->pubsetbuf(c, 256);ss << "hello ";ss << "world!";ss << std::endl;ss << "I'm c++ developer!";std::cout << "--------1--------\n";std::cout << ss.str() << std::endl;std::cout << "--------2--------\n";std::cout << c << std::endl;
}
//out log
--------1--------
hello world!
I'm c++ developer!
--------2--------
hello world!
I'm c++ developer!
上述代码,将一个字符数组设置为stringstream的缓冲序列,stringstream对象输入输出的数据均就改换成这个字符数组存储管理,可看到通过str函数(返回值对象是stringbuf)输出stringstream的存储内容和直接输出字符数组内容是一致的。
同一字符数组可以先后与不同字符串流 (str_in 或 str_out) 建立关联,分别对用一字符数组进行操作,甚至可以对字符数组交叉进行读写。
1.5 字符串流的打开模式
虽然说stringstream不像文件流一样需要打开文件,没有提供如open这样的函数,但是stringstream可以把缓冲内存块看着是文件,它同样具有打开模式的设置,主要体现在其构造函数中(istringstream/ostringstream类似):
/*以默认打开模式构造新的底层字符串设备*/
basic_stringstream(): basic_stringstream(std::ios_base::in | std::ios_base::out) { }//(C++11 起) /*构造新的底层字符串设备。
*以 basic_stringbuf<Char,Traits,Allocator>(mode) 构造底层 basic_stringbuf 对象*/
explicit basic_stringstream( std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out );// (C++11 前)
explicit basic_stringstream( std::ios_base::openmode mode );//(C++11 起) /*以 str 的副本为底层字符串设备的初始内容。
*以 basic_stringbuf<Char,Traits,Allocator>(str, mode) 构造底层 basic_stringbuf 对象。*/
explicit basic_stringstream( const std::basic_string<CharT,Traits,Allocator>& str,std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out );/*移动构造函数。用移动语义,构造拥有 other 的状态的字符串流。*/
basic_stringstream( basic_stringstream&& other );// (C++11 起) /*构造新的底层字符串设备。
*以 basic_stringbuf<Char,Traits,Allocator>(mode, a) 构造底层 basic_stringbuf 对象。*/
basic_stringstream( std::ios_base::openmode mode, const Allocator& a );//(C++20 起) /*用 str 移动构造底层字符串设备的内容。
*以basic_stringbuf<Char,Traits,Allocator>(std::move(str), mode)构造basic_stringbuf对象*/
explicit basic_stringstream( std::basic_string<CharT,Traits,Allocator>&& str,std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out );//(C++20 起) /*构造新的底层字符串设备。
*以basic_stringbuf<Char,Traits,Allocator>(str, std::ios_base::in | std::ios_base::out, a)
*构造底层 basic_stringbuf 对象。*/
template<class SAlloc>
basic_stringstream( const std::basic_string<CharT,Traits,SAlloc>& str,const Allocator& a ): basic_stringstream(str, std::ios_base::in | std::ios_base::out, a) { } //(C++20 起) /*构造新的底层字符串设备。
*以 basic_stringbuf<Char,Traits,Allocator>(str, mode, a) 构造底层 basic_stringbuf 对象。*/
template<class SAlloc>
basic_stringstream( const std::basic_string<CharT,Traits,SAlloc>& str,std::ios_base::openmode mode, const Allocator& a ); // (C++20 起)
/*构造新的底层字符串设备。
*以 basic_stringbuf<Char,Traits,Allocator>(str, mode) 构造底层 basic_stringbuf 对象。
*此重载仅若 SAlloc 与 Allocator 不是同一类型才参与重载决议。*/
template<class SAlloc>
explicit basic_stringstream( const std::basic_string<CharT,Traits,SAlloc>& str,std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out ); // (C++20 起)
在构造时可显示指定打开标志,这些数值是下列常量的组合(‘|’):
app 每次写入前寻位到流结尾
binary 以二进制模式打开
in 为读打开
out 为写打开
trunc 在打开时舍弃流的内容
ate 打开后立即寻位到流结尾
字符串流类没有open成员函数, 通过调用构造函数建立字符串流对象。支持传入指向字符数组首元素的指针, 用它来初始化流对象,可以设置openmode,是上述常量的组合,显式指明操作方式。
void basic_stringstream_test2(void)
{char c;std::istringstream in; //std::stringstream in(std::ios_base::in); //实际in.str("a b");in >> c;std::cout << "c = " << c << ", str() = \"" << in.str() << "\"\n";// in << 'c'; //error,无效,不存在该功能std::ostringstream out("a b");//std::ostringstream out("a b",std::ios_base::out);//实际out << 'c';std::cout << "str() = \"" << out.str() << "\"\n";// out >> c; //error,无效,不存在该功能std::stringstream ate1("a b ", std::ios_base::ate);ate1 << 'c'; //编译正确,但无效。std::ios_base::out没开启std::cout << "ate1.str() = \"" << ate1.str() << "\"\n";std::stringstream ate2("a b ", std::ios_base::out | std::ios_base::ate);ate2 << 'c';std::cout << "ate2.str() = \"" << ate2.str() << "\"\n";
}
二、字符串流的运用
2.1 格式转换是其拿手好戏
stringstream支持有格式输入输出(operator<</operator>>),stringstream通常是用来做数据转换的,用于字符串与其他变量类型的转换,它是安全,自动和直接的。通过字符串流从字符数组或字符串读数据就如同从键盘读数据一样, 可以从字符数组读入字符数据, 也可以读入整数, 浮点数或其他类型数据。
//类似的可以写出其他类型的转换,或采用模板函数实现各种类型转换
int strToInt(const char* str)
{int ret = 0;std::stringstream strBufer(str);if(!(strBufer>>ret))std::cout << "strToInt error"<< std::endl;return ret;
}void stringstream_user_test1(void)
{std::string str1("hello 1234 0 4.368");std::stringstream ss(str1);//构造函数初始化std::cout<<ss.str()<<std::endl;std::string str2;if(ss>>str2){std::cout << "str2 = " << str2 << std::endl;}int a;if(ss>>a){std::cout << "a = " << a << std::endl;}bool b;// ss>>std::boolalpha;if(ss>>b){std::cout << "b = " << b << std::endl;}float c;if(ss>>c){std::cout << "c = " << c << std::endl;}ss.clear();ss.str(" I am learning c++ stringstream!");//重新赋值while(ss>>str2)//不断读取{ std::cout<<str2<<" ";} std::cout << std::endl;const char *pi = "1314";std::cout << "strToInt(pi) = " << strToInt(pi) << std::endl;
}
//out log
hello 1234 0 4.368
str2 = hello
a = 1234
b = 0
c = 4.368
I am learning c++ stringstream!
strToInt(pi) = 1314
在实际开发过程中,对于那些悬而未决的混合字段信息,采用stringstream系列来存储,等到具体数据处理实现时再添加确切类型支持是个不错的选择。
2.2 字符串流仅提供移动赋值
stringstream系列类型支持移动赋值,但不支持复制赋值,它是通过stringbuf来熟悉的:
//std::basic_stringbuf<CharT,Traits,Allocator>::operator=
/*
*移动赋值运算符:移动 rhs 的内容到 *this 中。
*移动后 *this 拥有 rhs 之前保有的关联 string 、打开模式、本地环境和所有其他状态。
*保证 *this 中 std::basic_streambuf 的六个指针有别于被移动的 rhs 的对应指针,除非它们为空。
*/
std::basic_stringbuf& operator=( std::basic_stringbuf&& rhs );// (C++11 起) /*复制赋值运算符被删除;basic_stringbuf 不可复制赋值 (CopyAssignable) 。*/
std::basic_stringbuf& operator=( const std::basic_stringbuf& rhs ) = delete;//std::basic_stringstream::operator=
/*
*移动赋值字符串流 other 给 *this 。
*/
basic_stringstream& operator=( basic_stringstream&& other );//(C++11 起)
stringstream对象的移动赋值,等效的移动赋值 std::basic_iostream 基类和关联的 std::basic_stringbuf,基类移动赋值交换 *this 与 other 间的所有流状态变量(除了 rdbuf ),other 的内容被清除,流状态被重置。
void stringstream_user_test2(void)
{std::stringstream in("in");std::stringstream out("out");std::cout << "Before move, int = \"" << in.str() << '"'<< " out = \"" << out.str() << "\"\n";*in.rdbuf() = std::move(*out.rdbuf());std::cout << "After move, in = \"" << in.str() << '"'<< " out = \"" << out.str() << "\"\n";std::stringstream ss;ss = std::move(in);std::cout << "After move again, in = \"" << in.str() << '"'<< " ss = \"" << ss.str() << "\"\n";
}
//out log
Before move, int = "in" out = "out"
After move, in = "out" out = ""
After move again, in = "" ss = "out"
如果想与other的字符串流交换它们的内容及流状态,就采用交换函数swap。
//std::basic_stringstream::swap
//交换流与 other 的状态。
void swap( basic_stringstream& other );//(C++11 起)
stringstream对象的交换实现,本质上是通过调用 basic_iostream<CharT, Traits>::swap(other) 和 rdbuf()->swap(*other.rdbuf()) 进行。
void stringstream_user_test3(void)
{std::stringstream in("in");std::stringstream out("out");std::cout << "Before swap, int = \"" << in.str() << '"'<< " out = \"" << out.str() << "\"\n";in.swap(out);//out.swap(in);std::cout << "After swap, in = \"" << in.str() << '"'<< " out = \"" << out.str() << "\"\n";
}
//out log
Before swap, int = "in" out = "out"
After swap, in = "out" out = "in"
2.3 std::basic_stringstream不仅仅是字符串支持
需要记住的是std::basic_stringstream是一个类模板,stringstream是其特化类而已,采用std::basic_stringstream支持其他类型也可以实现类似流效果:
void stringstream_user_test4(void)
{int a[10] = {1,2,3,4,5,6};std::basic_stringstream<int> ss(a);// std::basic_stringstream<int> ss; // ss.rdbuf()->pubsetbuf(a, 10);int n = 0;int index = 0;while(index<6 && ss.read(&n,1)){std::cout << " a["<<index<<"] = " << n << "\n";++index;}
}
//out loga[0] = 1a[1] = 2a[2] = 3a[3] = 4a[4] = 5a[5] = 6
2.4 字符串流在信息拼接上也有独到之处
相对于用stringstream将字段信息拆分获得不同数据类型的信息,也可以采用stringstream类将不同类型的数据信息进行混合拼接,获得所需的字段信息,这在词汇组织处理上有独到之处。
void stringstream_user_test5(void)
{std::stringstream ss;int a = 34;int b = 27;ss << "now we count " << a <<" multiply " << b <<" the val is " << a*b;std::cout << "ss = \"" << ss.str() << "\"\n";
}
//out log
ss = "now we count 34 multiply 27 the val is 918"
关于字符串流IO的主要内容介绍到此结束!
感谢读友能耐心看到最后,本人文章都很长,知识点很细,可能会有所遗漏和失误,如果有不妥之处,烦请指出。如果内容对您有所触动,请点赞关注一下防止不迷路。
三、演示源代码补充
编译指令:g++ main.cpp test*.cpp -o test.exe -std=c++11
main.cpp
#include "test1.h"int main(int argc, char* argv[])
{stringstream_first_test();basic_stringstream_test();basic_stringstream_test1();basic_stringstream_test2();stringstream_user_test1();stringstream_user_test2();stringstream_user_test3();stringstream_user_test4();stringstream_user_test5();return 0;
}
test1.h
#ifndef _TEST_1_H_
#define _TEST_1_H_void stringstream_first_test(void);
void basic_stringstream_test(void);
void basic_stringstream_test1(void);
void basic_stringstream_test2(void);
void stringstream_user_test1(void);
void stringstream_user_test2(void);
void stringstream_user_test3(void);
void stringstream_user_test4(void);
void stringstream_user_test5(void);
#endif //_TEST_1_H_
test1.cpp
#include "test1.h"#include <iostream>
#include <sstream>void stringstream_first_test(void)
{std::stringstream ss;ss << "hello ";ss << "world!";ss << std::endl;ss << "I'm c++ developer!";std::cout << ss.str() << std::endl;
}void basic_stringstream_test(void)
{std::basic_stringstream<char> ss;ss << "hello ";ss << "world!";ss << std::endl;ss << "I'm c++ developer!";std::cout << ss.str() << std::endl;
}void basic_stringstream_test1(void)
{std::basic_stringstream<char> ss;char c[256] = {0};ss.rdbuf()->pubsetbuf(c, 256);ss << "hello ";ss << "world!";ss << std::endl;ss << "I'm c++ developer!";std::cout << "--------1--------\n";std::cout << ss.str() << std::endl;std::cout << "--------2--------\n";std::cout << c << std::endl;
}void basic_stringstream_test2(void)
{char c;std::istringstream in; //std::stringstream in(std::ios_base::in); //实际in.str("a b");in >> c;std::cout << "c = " << c << ", str() = \"" << in.str() << "\"\n";// in << 'c'; //error,无效,不存在该功能std::ostringstream out("a b");//std::ostringstream out("a b",std::ios_base::out);//实际out << 'c';std::cout << "str() = \"" << out.str() << "\"\n";// out >> c; //error,无效,不存在该功能std::stringstream ate1("a b ", std::ios_base::ate);ate1 << 'c'; //编译正确,但无效。std::ios_base::out没开启std::cout << "ate1.str() = \"" << ate1.str() << "\"\n";std::stringstream ate2("a b ", std::ios_base::out | std::ios_base::ate);ate2 << 'c';std::cout << "ate2.str() = \"" << ate2.str() << "\"\n";
}
//类似的可以写出其他类型的转换,或采用模板函数实现各种类型转换
int strToInt(const char* str)
{int ret = 0;std::stringstream strBufer(str);if(!(strBufer>>ret))std::cout << "strToInt error"<< std::endl;return ret;
}void stringstream_user_test1(void)
{std::string str1("hello 1234 0 4.368");std::stringstream ss(str1);//构造函数初始化std::cout<<ss.str()<<std::endl;std::string str2;if(ss>>str2){std::cout << "str2 = " << str2 << std::endl;}int a;if(ss>>a){std::cout << "a = " << a << std::endl;}bool b;// ss>>std::boolalpha;if(ss>>b){std::cout << "b = " << b << std::endl;}float c;if(ss>>c){std::cout << "c = " << c << std::endl;}ss.clear();ss.str(" I am learning c++ stringstream!");//重新赋值while(ss>>str2)//不断读取{ std::cout<<str2<<" ";} std::cout << std::endl;const char *pi = "1314";std::cout << "strToInt(pi) = " << strToInt(pi) << std::endl;
}void stringstream_user_test2(void)
{std::stringstream in("in");std::stringstream out("out");std::cout << "Before move, int = \"" << in.str() << '"'<< " out = \"" << out.str() << "\"\n";*in.rdbuf() = std::move(*out.rdbuf());std::cout << "After move, in = \"" << in.str() << '"'<< " out = \"" << out.str() << "\"\n";std::stringstream ss;ss = std::move(in);std::cout << "After move again, in = \"" << in.str() << '"'<< " ss = \"" << ss.str() << "\"\n";
}void stringstream_user_test3(void)
{std::stringstream in("in");std::stringstream out("out");std::cout << "Before swap, int = \"" << in.str() << '"'<< " out = \"" << out.str() << "\"\n";in.swap(out);//out.swap(in);std::cout << "After swap, in = \"" << in.str() << '"'<< " out = \"" << out.str() << "\"\n";
}void stringstream_user_test4(void)
{int a[10] = {1,2,3,4,5,6};std::basic_stringstream<int> ss(a);// std::basic_stringstream<int> ss; // ss.rdbuf()->pubsetbuf(a, 10);int n = 0;int index = 0;while(index<6 && ss.read(&n,1)){std::cout << " a["<<index<<"] = " << n << "\n";++index;}
}void stringstream_user_test5(void)
{std::stringstream ss;int a = 34;int b = 27;ss << "now we count " << a <<" multiply " << b <<" the val is " << a*b;std::cout << "ss = \"" << ss.str() << "\"\n";
}
相关文章:
C/C++开发,无可避免的IO输入/输出(篇三).字符串流(内存流)IO处理
目录 一、字符串流 1.1 字符串流继承体系 1.2 字符串流本质-类模板std::basic_stringstream 1.3 字符串流缓冲-std::stringbuf 1.4 stringbuf与序列缓冲 1.5 字符串流的打开模式 二、字符串流的运用 2.1 格式转换是其拿手好戏 2.2 字符串流仅提供移动赋值 2.3 std::basic_str…...
什么是HTTP请求?【JavaWeb技术】
HTTP请求是指从客户端到服务器的请求消息,建立HTTP请求需要经历以下7个步骤才能请求成功。 (1)建立TCP连接 在HTTP开始工作前,Web浏览器需先通过网络和Web服务器连接,连接过程主要使用TCP/IP完成。 (2)Web浏览器向Web服务器发送请求命令 一旦…...
浅聊面试这件事
目录 哪个时间点适合跳槽 如何准备面试 面试原则 面试常见问题 哪个时间点适合跳槽 金三银四、金九银十,这些都📌标记为我们的最佳跳槽节点,但是这些节点真的是最佳的么,也需要因人而异。 如果公司年前不发年终奖,…...
【致敬未来的攻城狮计划】连续打卡第7天+瑞萨RA2E1点亮LED
开启攻城狮的成长之旅!这是我参与的由 CSDN博客专家 架构师李肯(http://yyds.recan-li.cn)和 瑞萨MCU (瑞萨电子 (Renesas Electronics Corporation) ) 联合发起的「 致敬未来的攻城狮计划 」的第 7 天,点击…...
Sam Altman专访:GPT-4没太让我惊讶,ChatGPT则让我喜出望外
导读ChatGPT、GPT-4 无疑是 2023 年年初人工智能界最大的「爆款」。3 月 26 日,OpenAI CEO、ChatGPT 之父 Sam Altman 接受了著名学者与科技播客、麻省理工大学研究员 Lex Fridman 的专访,Sam 分享了从OpenAI内部视角如何看待ChatGPT和GPT-4的里程碑式意…...
弯道超车的机会
弯道超车的机会 原文地址:https://bmft.tech/#/1-throught/0302-chance 前言 我一直很想把自己思考的东西表达出来,苦于语文成绩差,文字功力不够,想来想去也不知道用什么话来开场。我不喜欢站在高处对别人指指点点,…...
【设计模式】创建型模式之原型模式
【设计模式】创建型模式之原型模式 文章目录【设计模式】创建型模式之原型模式1.概述2. 构成3. 实现3.1 浅克隆3.2 深克隆1.概述 原型模式(Prototype Pattern):是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它…...
KMP算法——我欲修仙(功法篇)
个人主页:【😊个人主页】 系列专栏:【❤️我欲修仙】 学习名言:莫等闲、白了少年头,空悲切。——岳飞 系列文章目录 第一章 ❤️ 学习前的必知知识 第二章 ❤️ 二分查找 文章目录系列文章目录前言🚗&…...
【嵌入式Linux学习笔记】QT在Linux嵌入式设备上的使用
QT是目前主流的UI界面设计软件之一,Linux系统也支持QT应用,并且提供了很多方便的接口。所以有必要记录一下基于QT,在LCD屏幕上实现UI界面功能的各种细节。 学习视频地址:【正点原子】STM32MP157开发板 1. 系统配置 出于方便&am…...
js根据数据关键字实现模糊查询功能
js根据数据关键字实现模糊查询功能模糊查询实现模糊查询功能的步骤和一般方法第一步:创建假数据或请求接口数据第二步:分析数据格式,处理数据第三步:验证功能完整代码模糊查询 模糊查询功能是指在搜索或者查询时,允许…...
java获取对象属性
Field[] fields vo.getClass().getDeclaredFields(); for (Field field : fields) {//设置允许通过反射访问私有变量field.setAccessible(true);//获取字段的值String value "";Class<?> type field.getType();if (Date.class.equals(type)) {value DateU…...
51单片机(IIC协议OLED屏)
一、IIC协议 1、IIC协议概述 1.1、概述:IIC全称Inter-Integrated Circuit (集成电路总线) 是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双 工同步通信方式 1.2、特点:简单性和有效性。 由于接口直…...
你知道,华为对项目经理要求的3项技能5项素质是什么吗?
很多人一定在好奇,华为对项目经理的要求是什么呢?普通项目经理应具备什么素质,才能进入华为这样的大厂,在严峻的经济形势下无惧裁员呢? 一、三项软技能 我们在华为举办的项目经理论坛中找到了答案:对于华…...
优漫动游 提升效率常用的C4D技巧
C4D是近几年非常热的趋势,经常有人问3D相关的问题,想把自己在找捷径的过程中觉得最实用的小技巧分享给大家 1、快速定位层级和模型 模型的过程中,经常遇到模型层级多难定位的问题,逐级打开或者全部展开对于定位模型使…...
基于蚁群算法的时间窗口路径优化
目录 背影 蚁群算法的原理及步骤 基本定义 编程思路 适应度函数 算法的规则 特点 主要参数 代码 结果分析 展望 背影 现代物流配送对时间要求更高,是否及时配送是配送是否成功的重要指标,本文对路径优化加时间窗口,实现基于蚁群算法的时间窗口路径优化, 蚁群算法 基本…...
liunx
linux常用命令 mkdir :创建文件夹 rm -f :删除文件 docker cp 文件名 20f:容器内地址 将文件从linux系统移动到docker地址 ln -s 将两个文件做链接 compgen -u 查看所有用户 groups 查看所在组 vim 编辑 quit 退出 sudo su - root 获得root权限 cp dir1/…...
机动车发票组件【vue】
发票组件 问题反馈:在这就可以 Install-下载 npm install motorvehicles --savewarrning:我们推荐您设置key的,因为不存在它会带来数据的复用性问题usage-使用说明 import MotorVehiclesIvoice from motorvehiclesimport MotorVehiclesIvo…...
学习笔记-剖析k8s之StatefulSet的拓扑状态-3月day18
文章目录前言StatefulSetHeadless ServicePod的拓扑状态小结附前言 Deployment实际上并不足以覆盖所有的应用编排问题,原因在于Deployment对应用做了一个简单化的假设:一个应用的所有Pod,是完全一样的。所以,它们互相之间没有顺序…...
Java实现输出九九乘法口诀表,输入行数输出对应的梯形(平行四边形)这两个代码
目录 一、前言 二、代码部分 1.输出九九乘法口诀表的代码 三、程序运行结果(控制台输出) 一、前言 1.本代码是我在上学时写的,有一些地方没能完美实现,请包涵也请多赐教! 2.本弹窗界面可以根据简单的要求进行输…...
C++空间配置器
目录 1.什么是空间配置器 2.为什么需要空间配置器 3.SGI-STL空间配置器实现原理 3.1一级空间配置器 3.2二级空间配置器 3.2.1内存池 3.2.2 SGI-STL中二级空间配置器设计 3.3 空间配置器的默认选择 4.空间配置器与容器的结合 1.什么是空间配置器 空间配置器࿰…...
JConsole使用教程
JConsole是一个Java虚拟机的监控和管理工具,可以监控Java应用程序的内存使用、线程和类信息等。 以下是JConsole的使用教程: 1.启动JConsole JConsole是一个Java自带的工具,可以在bin目录下找到jconsole.exe文件。双击运行该文件即可启动JC…...
JS手写防抖和节流函数(超详细版整理)
1、什么是防抖和节流防抖(debounce):每次触发定时器后,取消上一个定时器,然后重新触发定时器。防抖一般用于用户未知行为的优化,比如搜索框输入弹窗提示,因为用户接下来要输入的内容都是未知的&…...
我的Macbook pro使用体验
刚拿到Mac那一刻,第一眼很惊艳,不经眼前一亮,心想:这是一件艺术品,太好看了吧 而后再体验全新的Macos 系统,身为多年的win用户说实话一时间还是难以接受 1.从未见过的访达,不习惯的右键 2. …...
炼石入选“首届工业和信息化领域商用密码应用峰会”典型方案
2023年3月22日-23日,浙江省经济和信息化厅、浙江省通信管理局、浙江省密码管理局、工业和信息化部商用密码应用产业促进联盟联合举办的“首届工业和信息化领域商用密码应用峰会”(以下简称峰会)在浙江杭州成功举办,旨在深入推进工…...
使用new bing chat成功了
步骤一:在扩展商店搜索并安装modheader 打开浏览器; 点击右上角的三个点图标,选择“更多工具” -> “扩展程序”; 在扩展程序页面上方的搜索框中输入“modheader”,然后点击“搜索商店”; 在搜索结果中找到“ModHeader”扩展程序,点击“添加至”按钮,然后再点击“添…...
Golang每日一练(leetDay0019)
目录 55. 跳跃游戏 Jump Game 🌟🌟 56. 合并区间 Mmerge Intervals 🌟🌟 57. 插入区间 Insert Interval 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练…...
记录一次性能测试遇到的问题
零、压测指标问题 压测指标,一定要需求方定 啊,谁提压测需求,谁来定压测指标。 如果需求方,对压测指标没有概念,研发和测试,可以把历史压测指标、生产数据导出来给需求方看,引导他们来定指标&…...
C++运算符重载基础教程
所谓重载,就是赋予新的含义。函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作。运算符重载(Operator Overloading)也是一个道理,同一个运算符可以有不同…...
Git命令总结
全局配置 git config --global user.name ‘你的名字’ git config --global user.email ‘你的邮箱’ 当前仓库配置 git config --local user.name ‘你的名字’ git config --local user.email ‘你的邮箱’ 查看 global 配置 git config --global --list 查看当前仓库…...
【车载以太网】BCM89572A0BCFBG、BCM89559GB0BCFBG、BCM89559GA0BCFBG具有安全启动和安全通信功能
BCM89572A0BCFBG 设备是Broadcom第六代完全集成的L2多层开关解决方案,支持车载网络应用的汽车认证(AEC-Q100)和温度等级。BCM8956X系列产品为汽车行业提高了具有多种一流功能的交换机的标准,例如802.1AE MACsec等集成安全功能,增加了主机连接…...
公司可以做多个网站吗/推广普通话手抄报简单又好看内容
关于代码的一切尽在「代码随想录」什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点是由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。链表的类型…...
网站建设的商业阶段/百度seo营销推广多少钱
oracle the account is locked 提示账号被锁了,不是密码不对,使用命令: alter user scott account unlock;如果密码不对,可以再修改: alter user scott identified by tiger;用sys以sysdba的身份来进行登录, / as sysd…...
最新招总代理项目/无锡seo
XUnit入门 1.如果之前安装了xUnit.net Visual Studio Runner扩展包,通过"工具"菜单下的"扩展和更新"先将该扩展包卸载。 2.删除临时目录中的指定文件夹:%TEMP%\VisualStudioTestExplorerExtensions 安装Xunit: Xunit的安…...
西宁建设网站多少钱/深圳网络优化seo
文章目录1.返回Car2.返回List< Car >3.返回map集合4.返回List< Map >5. 返回Map<String, Map>6.结果映射6.1 使用resultMap6.2 开启驼峰命名7.返回总记录条数1.返回Car CarMapper.xml <select id"selectById" resultType"Car">se…...
酒店网站建设策划方案/国内专业seo公司
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。这一模式镇中关键对象是目标(subject)和观察者(observer)。一个目标可以有任意数目的依…...
四方坪网站建设/东莞网站建设最牛
转载:http://www.cnblogs.com/woider/p/5926744.html pymysql 由于 MySQLdb 模块还不支持 Python3.x,所以 Python3.x 如果想连接MySQL需要安装 pymysql 模块。 pymysql 模块可以通过 pip 安装。但如果你使用的是 pycharm IDE,则可以使用 proj…...