sprintf, snprintf, _snprintf, sprintf_s 等的区别

2023-11-12

先放结论

1.在支持snpritf的编译器 ,只使用int snprintf( char *buffer, size_t count, const char *format [, argument] ... );

无论成功或者失败,都会返回字符串的总长度(不包括结束符),如果buffer的大小不足以存放,那么就会截断。buffer里格式化的字符串带结束符。

2.在旧版本的Visual Studio例如vs2005, 不支持snprintf函数。

使用int _snprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format [, argument] ... );

用法: sizeOfBuffer参数永远填"缓冲区的大小-1", count参数永远填_TRUNCATE,  

char buf[4];
int sp_ret = _snprintf_s(buf, sizeof(buf) - 1, _TRUNCATE, "1234%d", 5);

成功则返回字符串长度, 如果buffer大小不足以存放字符串,则返回-1,字符串会截断保存在buffer里,带字符串结束符。

上面例子返回-1, buf里的数据是"123\0"。

 

总结

1.sprintf,参数不带缓冲区长度, 成功返回字符串长度, 格式化的字符串带结束符, 编译器都支持。 越界了程序不会立刻崩溃,难以发现。

2.snprintf,  参数带缓冲区长度,成功返回字符串长度, 格式化的字符串带结束符, 缓冲区不足时截断字符串,同时返回格式化字符串需要的buffer长度(不包括结束符)。 新版本的Visual Studio才支持,老版本无法使用。 安全。

3.sprintf_s, 参数带缓冲区长度,成功返回字符串长度,缓冲区不足时直接抛异常,程序崩溃。 新旧版本的Visual Studio都支持。 release版不建议使用,因为一旦缓冲区不足,异常没处理好,程序就挂了。

4._snprintfsnprintf差不多,唯一区别就是当字符串不算结束符的长度刚好跟缓冲区一样长的时候, 也会成功并把字符串写到缓冲区,这时候缓冲区是不带结束符的,建议用snprintf代替,避免后面的代码误以为字符串带结束符导致出错或者后面代码每次都要检查长度逻辑反而复杂化。

5.微软的一系列函数中,函数开头带_表示微软在c/c++标准以外的实现, _s的表示安全加强版本,参数错误例如缓冲区长度不足程序会抛异常,带w表示宽字符版本, 带_l的表示带locale_t参数的版本。

例如strcpy是标准里的函数, strcpy_s是安全加强版本, 虽然在c++11以后才有,但是老版本的Visual Studio就支持这个函数, 同样sprintf_ssprintf对应的安全版本。 在VS2015以后,不带安全版本的字符串函数都废弃(deprecated)了, 如果使用了,编译器会报警。

例如sprintf处理char字符串, 宽字符版本的字符串wchar_t就用swprintf, 同样地_snprintf对应_snwprintf, _snprintf_s对应_snwprintf_s

例如atof对应的多一个locale_t参数的函数是_atof_l,  _snprintf_s对应_snprintf_s_l_snwprintf_s对应_snwprintf_s_l

6.sprintf以及snprintf都是跨平台可用。其他的我测试只在Windows平台可用。另外snprintf属于C99的内容,在Visual Studio老版本不能使用,只能用_snprintf等代替。

反正使劲并且只用snprintf就对了。除非在Windows平台并且用老古董的Visual Studio。另外strcpystrcat等也换成strncpy, strncat(C99以后支持,并且不支持C99的VS老版本也支持)


1. int sprintf( char *buffer, const char *format [, argument] ... );

如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。

例子A:缓冲区足够放下整个字符串

char buf[4];
int sp_ret;
sp_ret = sprintf(buf, "12%d", 3);

成功, 返回3, 并且buf里的内容是"123\0" 一共4个字节。

例子B:缓冲区不足

char buf[4];
int sp_ret;
sp_ret = sprintf(buf, "123%d", 4);

返回值为4,内存越界,就是当时不死,也是迟早要完。


2. int snprintf( char *buffer, size_t count, const char *format [, argument] ... );

比sprinf多一个count参数,标识缓冲区的长度,避免越界,更加安全。

例子A:缓冲区足够放下整个字符串

char buf[4];
int sp_ret;
sp_ret = snprintf(buf, sizeof(buf), "12%d", 3);

成功,  返回3,  buf数据"123\0" 一共4个字节。 跟sprintf的表现差不多。

例子B:缓冲区不足

char buf[4];
int sp_ret;
sp_ret = snprintf(buf, sizeof(buf), "123%d", 4);

成功,返回4, buf数据"123\0" 一共4个字节。 目标字符串会被截断成buf刚好能放下的字符串(包括字符串结束符null terminator)。

char buf[4];
int sp_ret;
sp_ret = snprintf(buf, sizeof(buf), "1234%d", 5);

成功,返回5, buf数据"123\0" 一共4个字节。 目标字符串会被截断成buf刚好能放下的字符串(包括字符串结束符null terminator)。


3. int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format, ... );

跟sprintf对应,后面_s 代表 security, 是微软CRT函数针对sprintf函数的安全增强版,早在Vs2005版本就可以使用, 新版本的Visual Studio应该是2015以后,对sprintf函数标识为废弃,编译器就会提示警告,并且建议使用安全版本。 sprintf_s相比sprintf函数多了个sizeOfBuffer参数, 指定buffer的长度,避免越界。 

例子A:缓冲区充足

char buf[4];
int sp_ret;
sp_ret = sprintf_s(buf, sizeof(buf), "12%d", 3);

成功,  返回3,  buf数据"123\0" 一共4个字节。 

例子B:缓冲区不足(字符串结束符也要算)

char buf[4];
int sp_ret;
sp_ret = sprintf_s(buf, sizeof(buf), "123%d", 4);

这时候,程序直接抛异常。。。说好的更加安全,原来是抛异常尽早发现问题,就是如此的暴力,且枯燥。 曾经有个项目,在客户环境跑60多天就会崩溃一次,最后发现是因为有个定时记录日志的地方,buffer缓冲区设置比较小, 随时时间推移,计数越来越大,终于60多天超过缓冲区导致进程崩了。就因为一个无关紧要的功能用了sprintf_s函数,导致整个程序崩溃, 同时崩溃的还有我弱小的心灵。 从此我再也不敢用_s的函数了。 很多时候,字符串格式化截断,还是一种可以接受的结果,例如发现日志,或者某个显示的字符串不完整,至少客户还能正常使用,程序员也勉强能看出缓冲区不足的问题,尽快修复。 因此我比较倾向于使用snprintf代替。

同理, strcpy_s, strcat_s等,都比原来的strcpy, strcat函数多了一个缓冲区长度参数,也是出错直接抛异常。建议使用strncpy, strncat代替。

 

template <size_t size>

int sprintf_s( char (&buffer)[size], const char *format, ... ); // C++ only

这是sprintf_s在c++的另外一个重载版本, char数组,通过模板获取到缓冲区的大小,可以少填长度参数。 跟原版功能是一样的。


4. int _snprintf( char *buffer, size_t count, const char *format [, argument] ... );

snprintf前面的多下划线‘_‘’前缀, 在低版本Visual Studio(例如vs2005)不支持C99,  微软提供了一系列的'_'开头的函数, _snprintf, _strncpy, _strncat等。 用于对字符串缓冲区操作时,指定长度防止越界。 sprintf不指定缓冲区长度实在不太安全。 到了高版本的Visual Studio, 这些_开头的函数依旧可以使用。C99标准增加了strncpy, strncat等, 如果c++标准里有的函数,尽量用标准的。

例子A:缓冲区充足

char buf[4];
int sp_ret;
sp_ret = _snprintf(buf, sizeof(buf), "12%d", 3);

成功,  返回3,  buf数据"123\0" 一共4个字节。 跟snprintf的表现一致。

例子B:缓冲区刚好放下字符串,但不包括字符串结束符。

char buf[4];
int sp_ret;
sp_ret = _snprintf(buf, sizeof(buf), "123%d", 4);

成功,返回4,  buf数据"1234" 一共4个字节。 没有字符串结束符。

例子C:缓冲区连不包括结束符的字符串都放不下。

char buf[4];
int sp_ret;
sp_ret = _snprintf(buf, sizeof(buf), "1234%d", 5);

失败,返回-1。 buf数据"1234" 一共4个字节。没有结束符的字符串还是格式化到buf了。

 

在高版本的Visual Studio因为支持c++标准的std::snprintf, 建议直接使用std::snprintf代替。

在低版本的Visual Studio,在使用_snprintf的时候,为了确保字符串像std::snprintf一样截断。需要以下面方式使用。

char buf[4];
int sp_ret;
sp_ret = _snprintf(buf, sizeof(buf) - 1, "1234%d", 5);
if (sp_ret == -1) { // buf不足,截断
	buf[sizeof(buf) - 1] = '\0';
}

传入的sizeof(buf) - 1确保至少保留一个字节用于字符串结束符。

当返回-1的时候,表示buf前面的sizeof(buf) - 1都已填充满数据,这时候最后一个字节是没有结束符的,需要手动添加。

以上方式使用起来还是比较麻烦,低版本VS建议用_snprintf_s来代替

char buf[4];
int sp_ret;
sp_ret = _snprintf_s(buf, sizeof(buf) - 1, sizeof(buf) - 1, "1234%d", 5);

或者

char buf[4];
int sp_ret;
sp_ret = _snprintf_s(buf, sizeof(buf) - 1, _TRUNCATE, "1234%d", 5);

5.int _snprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format [, argument] ... );

这个函数可以理解为 _snprintf + _s, 也就是_snprintf函数一模一样的功能, _s 意味着,安全,也意味着超过buffer长度就会崩溃。该函数vs2005就能用。

count是指字符串的最大长度。

当count参数等于sizeOfBuffer时,_snprintf_s的功能跟sprintf_s一模一样, 要么正常,要么崩溃。

当count参数等于sizeOfBuffer - 1或者 _TRUNCATE时,_snprintf_ssnprintf的功能一模一样,两个函数成功都是返回字符串的长度,失败_snprintf_s返回-1, 而snprintf返回字符串需要的总长度。#define _TRUNCATE ((size_t)-1), _TRUNCATE是一个特殊标识,告诉该函数如果字符串超过范围则截断。

当count参数少于sizeOfBuffer - 1时, 相当于有些可用的buffer也故意不让使用,这种用法有些奇怪。应该没人会这么用吧。

template <size_t size>

int _snprintf_s( char (&buffer)[size], size_t count, const char *format [, argument] ... ); // C++ only

这是_snprintf_s在c++的另外一个重载版本, char数组,通过模板获取到缓冲区的大小,可以少填长度参数。 跟原版功能是一样的。


6.

int _sprintf_l( char *buffer, const char *format, locale_t locale [, argument] ... );

locale:The locale to use.  

由于国家/语言的差异, 有些用于格式化的函数的行为在不同语言里并不相同。

例如我们浮点数表示"3.5", 但是在德国,浮点数不是用'.'分隔,而是用','。因此在德语中,应该表示为“3,5”。

这样atof函数在两个国家的格式化结果应该是不一样的。因此微软准备了一系列的_XXX_l函数,比正常的函数多一个locale_t参数。例如_sprintf_l对应sprint, _atof_l对应atof, _atoi_l对应atoi。而默认的XXX函数实际上底层调用的是_XXX_l(locale=NULL)。

因此sprintf函数底层应该是调用了_sprintf_l(buffer, format, NULL, ...)。

atof(str)实际上调用了_atof_l(str, NULL),  atoi(str)实际上调用了_atoi_l(str, NULL)。

更多与地区相关的函数参考https://docs.microsoft.com/en-us/cpp/c-runtime-library/locale?view=msvc-150

同理

int _snprintf_s_l( char *buffer, size_t sizeOfBuffer, size_t count, const char *format, locale_t locale [, argument] ... );

相当于_snprintf_s + _l。

 

另外由于宽字符wchar_t的存在,每一个对char的字符串操作都有一个宽字符的对应版本的函数

宽字符以及locale两两组合,每个函数都会出现4个版本。 如果是_snprintf等有sizeOfBuffer参数的, 通过模板重载自动识别sizeOfBuffer,函数形式再多一倍。
 

sprintf:

int sprintf( char *buffer, const char *format [, argument] ... ); 
int _sprintf_l( char *buffer, const char *format, locale_t locale [, argument] ... );
int swprintf( wchar_t *buffer, size_t count, const wchar_t *format [, argument]... ); 
int _swprintf_l( wchar_t *buffer, size_t count, const wchar_t *format, locale_t locale [, argument] ... );
template <size_t size>
int sprintf( char (&buffer)[size], const char *format [, argument] ... );
template <size_t size> 
int _sprintf_l( char (&buffer)[size], const char *format, locale_t locale [, argument] ... ); 

 

sprintf_s:

int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... );
int _sprintf_s_l( char *buffer, size_t sizeOfBuffer, const char *format, locale_t locale [, argument] ... );
int swprintf_s( wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format [, argument] ... );
int _swprintf_s_l( wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, locale_t locale [, argument] ... );
template <size_t size>
int sprintf_s( char (&buffer)[size], const char *format [, argument] ... );
template <size_t size>
int swprintf_s( wchar_t (&buffer)[size], const wchar_t *format [, argument] ... );

 

snprintf:

int snprintf( char *buffer, size_t count, const char *format [, argument] ... );
int _snprintf( char *buffer, size_t count, const char *format [, argument] ... );
int _snprintf_l( char *buffer, size_t count, const char *format, locale_t locale [, argument] ... );
int _snwprintf( wchar_t *buffer, size_t count, const wchar_t *format [, argument] ... );
int _snwprintf_l( wchar_t *buffer, size_t count, const wchar_t *format, locale_t locale [, argument] ... );
template <size_t size>
int _snprintf( char (&buffer)[size], size_t count, const char *format [, argument] ... ); 
template <size_t size>
int _snprintf_l( char (&buffer)[size], size_t count, const char *format, locale_t locale [, argument] ... );
template <size_t size>
int _snwprintf( wchar_t (&buffer)[size], size_t count, const wchar_t *format [, argument] ... );
template <size_t size>
int _snwprintf_l( wchar_t (&buffer)[size], size_t count, const wchar_t *format, locale_t locale [, argument] ... );

 

snprintf_s:

int _snprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format [, argument] ... ); 
int _snprintf_s_l( char *buffer, size_t sizeOfBuffer, size_t count, const char *format, locale_t locale [, argument] ... ); 
int _snwprintf_s( wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format [, argument] ... ); 
int _snwprintf_s_l( wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, locale_t locale [, argument] ... );
template <size_t size>
int _snprintf_s( char (&buffer)[size], size_t count, const char *format [, argument] ... ); 
template <size_t size>
int _snwprintf_s( wchar_t (&buffer)[size], size_t count, const wchar_t *format [, argument] ... );

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

sprintf, snprintf, _snprintf, sprintf_s 等的区别 的相关文章

  • 为什么使用abs()或fabs()而不是条件否定?

    在 C C 中 为什么要使用abs or fabs 不使用以下代码即可查找变量的绝对值 int absoluteValue value lt 0 value value 这与较低级别的指令较少有关吗 您提出的 有条件的abs 并不等于std
  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • GCC C++ (ARM) 和指向结构体字段的 const 指针

    假设有一个简单的测试代码 typedef struct int first int second int third type t define ADDRESS 0x12345678 define REGISTER type t ADDRE
  • MEX 文件中的断言导致 Matlab 崩溃

    我正在使用mxAssert 宏定义为matrix h在我的 C 代码中 mex 可以完美编译 当我调用的 mex 代码中违反断言时 该断言不会导致我的程序崩溃 而是导致 Matlab 本身崩溃 我错过了什么吗 这是有意的行为吗 当我查看 M
  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • 如何进行带有偏差的浮点舍入(始终向上或向下舍入)?

    我想以偏置舍入浮动 要么总是向下 要么总是向上 代码中有一个特定的点 我需要这个 程序的其余部分应该像往常一样四舍五入到最接近的值 例如 我想四舍五入到最接近的 1 10 倍数 最接近 7 10 的浮点数约为 0 69999998807 但
  • 为什么基类必须有一个带有 0 个参数的构造函数?

    这不会编译 namespace Constructor0Args class Base public Base int x class Derived Base class Program static void Main string a
  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • gdb 在 docker 上立即退出“进程已完成,退出代码 1”或 lldb“数据包返回错误 8”。另外:如何在 docker 中允许进行 C++ 调试

    这花了我一整天的时间才找到 所以我将其发布以供将来参考 我正在 docker 镜像上开发 C 我正在使用克利翁 我的代码是在调试模式下编译的 并且在运行模式下运行良好 但是当尝试调试时 进程会立即退出 并显示非常丰富的信息 Process
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • C# 创建数组的数组

    我正在尝试创建一个将使用重复数据的数组数组 如下所示 int list1 new int 4 1 2 3 4 int list2 new int 4 5 6 7 8 int list3 new int 4 1 3 2 1 int list4
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS
  • 如何创建向后兼容 Windows 7 的缩放和尺寸更改每显示器 DPI 感知应用程序?

    我是 WPF 和 DPI 感知 API 的新手 正在编写一个在 Windows 7 8 1 和 10 中运行的应用程序 我使用具有不同每个显示器 DPI 设置的多个显示器 并且有兴趣将我的应用程序制作为跨桌面配置尽可能兼容 我已经知道可以将

随机推荐

  • Mysql服务器的外部连接

    目录 前言 Windows上的客户端连接工具有 Linux上连接其他虚拟机上的MySQL服务器 在Windows上通过Navicat连接虚拟机上的Mysql服务器 1 我们先下载好Navicat 2 当我们下载安装好Navicat后 打开它
  • 用org.apache.tools.zip压缩/解压缩zip文件

    package org coolyongzi import java io File import java io FileInputStream import java io FileOutputStream import java io
  • android删除文件夹代码,Android 删除指定文件代码

    package com tware pdfdrop import java io File import android app Activity import android graphics Color import android o
  • LLVM系列第十五章:写一个简单的中间代码生成器IR Generator

    系列文章目录 LLVM系列第一章 编译LLVM源码 LLVM系列第二章 模块Module LLVM系列第三章 函数Function LLVM系列第四章 逻辑代码块Block LLVM系列第五章 全局变量Global Variable LLV
  • 关于2023美赛ABCDEF各题的选题

    本文是关于2023美赛各题的选题以及思路分析 占个位置 比赛开始后会在本帖实时更新赛题思路代码 文章末尾获取 持续为更新参考思路 赛题思路 会持续进行思路模型分析 下自行获取 A题思路 比赛开始后第一时间更新 B题思路 比赛开始后第一时间更
  • Qt 控件尺寸设置

    一 运行无误 Qt 的控件在显示时 有时运行没有问题 但是会有以下信息 QWindowsWindow setGeometry Unable to set geometry 247x97 1200 801 frame 273x168 1187
  • 【python、pycharm安装教程】python3.7和pycharm2019最详细安装教程

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 python3 7和pycharm2019最详细安装教程 一 安装python 二 安装Pycharm 安装路径中不要存在中文 一 安装python 1 双击运行python
  • java 根据word文档模板导出word

    1 创建word模板 2 动态数据占位 格式 xxxxx 3 点击另存为xml格式 4 修改后缀名为ftl 5 导入到idea中 6 修改文件编码为utf 8 7 复制模板内容在线代码格式化 8 编辑模板中内容 如果有空值会报错 可以 xx
  • R-应用流行病学和公共卫生-5.导入

    rio包 我们推荐的 R 包是 rio 名称 rio 是 RI O 输入 输出 的缩写 它的功能import 和export 可以处理许多不同的文件类型 例如 xlsx csv rds tsv 当您提供这些函数的文件路径 包括 csv 之类
  • 【React】hooks的原理

    https medium com ryardley react hooks not magic just arrays cd4f1857236e 参考了这篇文章 对hooks的实现有初步的了解 具体的还是得研究一下官方的 这篇文章用了一个简
  • pptp和l2tp有什么区别

    PPTP协议是点对点隧道协议 其将控制包与数据包分开 控制包采用TCP控制 用于严格的状态查询及信令信息 数据包部分先封装在PPP协议中 然后封装到GREV2协议中 L2TP是国际标准隧道协议 它结合了PPTP协议以及第二层转发L2F协议的
  • 转:基于 Python 和 Scikit-Learn 的机器学习介绍

    我叫Alex 我在机器学习和网络图分析 主要是理论 有所涉猎 我同时在为一家俄罗斯移动运营商开发大数据产品 这是我第一次在网上写文章 不喜勿喷 现在 很多人想开发高效的算法以及参加机器学习的竞赛 所以他们过来问我 该如何开始 一段时间以前
  • 7天学完Spring:基础学习结束,关于Spring事务及其传播机制

    目录 前言 一丶Spring中事务的实现 lt 1 gt MySQL中的事务使用 回顾 lt 2 gt 手动操作事务 lt 3 gt 自动操作事务 1 gt 作用域说明 2 gt 参数说明 3 gt Transactional 工作原理 二
  • PPPoE Server防止ARP***

    在一般情况下 只要有一台计算机感染ARP病毒就可能造成此网段中所有计算机上网时断时续或缓慢等其它不正常现象 为了保障网络正常运行 针对ARP病毒的猖獗和破坏性 我们也已有一些应对措施 这些措施有的尽管能解一时之急 但不能从根本上彻底解决问题
  • HIVE-执行命令的几种方式 和 hive -e 和hive -f的使用

    第一种 在bash中直接通过hive e命令 并用 gt 输出流把执行结果输出到制定文件 hive e select from test hour rate2 where year 2019 gt tmp output 1 txt 第二种
  • 流明(lux)和坎德拉;

    流明是光照度 坎德拉是光强 流明是光通量的单位 cd是光强单位 光强是单位立体角的光通量 照度是单位面积的光通量 尼特是亮度单位 1尼特 1CD m 2 1 lx 1 流明每平方米 面发光度 光照度 纸面的反射系数 发光强度1坎德拉 cd
  • C++中for( : )用法

    常用的遍历数组的写法 随机定义的数组 int array 10 1 2 3 4 5 6 7 8 9 10 for int i 0 i lt 10 i cout lt lt array i lt lt 输出 1 2 3 4 5 6 7 8 9
  • Vuex安装时报错“Could not resolve dependency: npm ERR peer vue@“^3.0.2“ from vuex@4.0.2”

    报错的原因 安装的版本过高的原因造成的 解决方法 1 可以npm view vuex versions json查版本 找适合的版本 不要最新的 2 npm install vuex 3 6 2 save根据版本下载 这样就可以了
  • 第七届蓝桥杯省赛C++A/B组 最大比例

    X星球的某个大奖赛设了 M 级奖励 每个级别的奖金是一个正整数 并且 相邻的两个级别间的比例是个固定值 也就是说 所有级别的奖金数构成了一个等比数列 比如 16 24 36 54 其等比值为 3 2 现在 我们随机调查了一些获奖者的奖金数
  • sprintf, snprintf, _snprintf, sprintf_s 等的区别

    先放结论 1 在支持snpritf的编译器 只使用int snprintf char buffer size t count const char format argument 无论成功或者失败 都会返回字符串的总长度 不包括结束符 如果