go语言scan函数详解 go语言scanf

基础知识 - Golang 中的格式化输入输出 【格式化输出】
// 格式化输出:将 arg 列表中的 arg 转换为字符串输出
// 使用动词 v 格式化 arg 列表,非字符串元素之间添加空格
Print(arg列表)
// 使用动词 v 格式化 arg 列表,所有元素之间添加空格,结尾添加换行符
Println(arg列表)
// 使用格式字符串格式化 arg 列表
Printf(格式字符串, arg列表)
// Print 类函数会返回已处理的 arg 数量和遇到的错误信息 。
【格式字符串】
格式字符串由普通字符和占位符组成,例如:
"abc%#8.3[3]vdef"
其中 abc 和 def 是普通字符,其它部分是占位符 , 占位符以 % 开头(注:%% 将被转义为一个普通的 % 符号 , 这个不算开头),以动词结尾,格式如下:
%[旗标][宽度][.精度][arg索引]动词
方括号中的内容可以省略 。
【旗标】
旗标有以下几种:
空格:对于数值类型的正数,保留一个空白的符号位(其它用法在动词部分说明) 。
0:用 0 进行宽度填充而不用空格,对于数值类型,符号将被移到所有 0 的前面 。
其中 "0" 和 "-" 不能同时使用,优先使用 "-" 而忽略 "0" 。
【宽度和精度】
“宽度”和“精度”都可以写成以下三种形式:
数值 | * | arg索引*
其中“数值”表示使用指定的数值作为宽度值或精度值,“ ”表示使用当前正在处理的 arg 的值作为宽度值或精度值,如果这样的话,要格式化的 arg 将自动跳转到下一个 。“arg索引 ”表示使用指定 arg 的值作为宽度值或精度值,如果这样的话,要格式化的 arg 将自动跳转到指定 arg 的下一个 。
宽度值:用于设置最小宽度 。
精度值:对于浮点型,用于控制小数位数,对于字符串或字节数组,用于控制字符数量(不是字节数量) 。
对于浮点型而言 , 动词 g/G 的精度值比较特殊,在适当的情况下 , g/G 会设置总有效数字,而不是小数位数 。
【arg 索引】
“arg索引”由中括号和 arg 序号组成(就像上面示例中的 [3]),用于指定当前要处理的 arg 的序号 , 序号从 1 开始:
'['arg序号']'
【动词】
“动词”不能省略,不同的数据类型支持的动词不一样 。
[通用动词]
v:默认格式,不同类型的默认格式如下:
布尔型:t
整 型:d
浮点型:g
复数型:g
字符串:s
通 道:p
指 针:p
无符号整型:x
T:输出 arg 的类型而不是值(使用 Go 语法格式) 。
[布尔型]
t:输出 true 或 false 字符串 。
[整型]
b/o/d:输出 2/8/10 进制格式
x/X:输出 16 进制格式(小写/大写)
c:输出数值所表示的 Unicode 字符
q:输出数值所表示的 Unicode 字符(带单引号) 。对于无法显示的字符,将输出其转义字符 。
U:输出 Unicode 码点(例如 U 1234 , 等同于字符串 "U X" 的显示结果)
对于 o/x/X:
如果使用 "#" 旗标,则会添加前导 0 或 0x 。
对于 U:
如果使用 "#" 旗标,则会在 Unicode 码点后面添加相应的 '字符'(前提是该字符必须可显示)
[浮点型和复数型]
b:科学计数法(以 2为底)
e/E:科学计数法(以 10 为底,小写 e/大写 E)
f/F:普通小数格式(两者无区别)
g/G:大指数(指数 = 6)使用 %e/%E,其它情况使用 %f/%F
[字符串或字节切片]
s:普通字符串
q:双引号引起来的 Go 语法字符串
x/X:十六进制编码(小写/大写,以字节为元素进行编码,而不是字符)
对于 q:
如果使用了 " " 旗标 , 则将所有非 ASCII 字符都进行转义处理 。
如果使用了 "#" 旗标 , 则输出反引号引起来的字符串(前提是
字符串中不包含任何制表符以外的控制字符,否则忽略 # 旗标)
对于 x/X:
如果使用了 " " 旗标,则在每个元素之间添加空格 。
如果使用了 "#" 旗标,则在十六进制格式之前添加 0x 前缀 。
[指针类型]
p :带 0x 前缀的十六进制地址值 。
[符合类型]
复合类型将使用不同的格式输出,格式如下:
结 构 体:{字段1 字段2 ...}
数组或切片:[元素0 元素1 ...]
映 射:map[键1:值1 键2:值2 ...]
指向符合元素的指针:{}, [], map[]
复合类型本身没有动词 , 动词将应用到复合类型的元素上 。
结构体可以使用 " v" 同时输出字段名 。
【注意】
1、如果 arg 是一个反射值 , 则该 arg 将被它所持有的具体值所取代 。
2、如果 arg 实现了 Formatter 接口 , 将调用它的 Format 方法完成格式化 。
3、如果 v 动词使用了 # 旗标(%#v),并且 arg 实现了 GoStringer 接口,将调用它的 GoString 方法完成格式化 。
如果格式化操作指定了字符串相关的动词(比如 %s、%q、%v、%x、%X),接下来的两条规则将适用:
4 。如果 arg 实现了 error 接口,将调用它的 Error 方法完成格式化 。
5 。如果 arg 实现了 string 接口,将调用它的 String 方法完成格式化 。
在实现格式化相关接口的时候,要避免无限递归的情况 , 比如:
type X string
func (x X) String() string {
return Sprintf("%s", x)
}
在格式化之前 , 要先转换数据类型 , 这样就可以避免无限递归:
func (x X) String() string {
return Sprintf("%s", string(x))
}
无限递归也可能发生在自引用数据类型上面,比如一个切片的元素引用了切片自身 。这种情况比较罕见,比如:
a := make([]interface{}, 1)
a[0] = a
fmt.Println(a)
【格式化输入】
// 格式化输入:从输入端读取字符串(以空白分隔的值的序列),
// 并解析为具体的值存入相应的 arg 中 , arg 必须是变量地址 。
// 字符串中的连续空白视为单个空白 , 换行符根据不同情况处理 。
// \r\n 被当做 \n 处理 。
// 以动词 v 解析字符串,换行视为空白
Scan(arg列表)
// 以动词 v 解析字符串,换行结束解析
Scanln(arg列表)
// 根据格式字符串中指定的格式解析字符串
// 格式字符串中的换行符必须和输入端的换行符相匹配 。
Scanf(格式字符串, arg列表)
// Scan 类函数会返回已处理的 arg 数量和遇到的错误信息 。
【格式字符串】
格式字符串类似于 Printf 中的格式字符串,但下面的动词和旗标例外:
p:无效
T:无效
e/E/f/F/g/G:功能相同,都是扫描浮点数或复数
s/v:对字符串而言,扫描一个被空白分隔的子串
对于整型 arg 而言,v 动词可以扫描带有前导 0 或 0x 的八进制或十六进制数值 。
宽度被用来指定最大扫描宽度(不会跨越空格) , 精度不被支持 。
如果 arg 实现了 Scanner 接口 , 将调用它的 Scan 方法扫描相应数据 。只有基础类型和实现了 Scanner 接口的类型可以使用 Scan 类方法进行扫描 。
【注意】
连续调用 FScan 可能会丢失数据 , 因为 FScan 中使用了 UnreadRune 对读取的数据进行撤销 , 而参数 io.Reader 只有 Read 方法,不支持撤销 。比如:
golang-redis系列——返回值助手函数(二) 从上一节的内容可知,Do() 和 Receive() 等方法的返回值,除了 error 外 , 是一个 interface{} 类型的返回值 , 因此当我们的复杂操作返回的不是基本数据类型时,就需要我们自己解析返回值,例如,当我们利用 HMGET 方法获取一批返回值时,就需要对返回结果进行解析,具体如下:
由于返回值是多条数据,因此需要先将 reply 转成 []interface 类型 , 然后在遍历结果时在分别转成 []uint8 (byte数组), 最后再转成 string 类型 。
随着我们操作复杂度,数据解析的工作量也会非常大,(lua 脚本的使用,会使结果的解析更为复杂,因为可能存在多种类型的结果一起返回的情况,lua 脚本相关的内容会在下一节介绍) 。
redigo 包中的返回值助手函数的存在 , 就是为了帮助我们完成这些枯燥繁琐的数据解析过程 。
返回值助手函数相关源码路径为github.com/gomodule/redigo/redis/reply.go提供的主要方法如下:
上述返回值助手函数的具体使用,应该依据具体的命令进行选择 。如果大家还记得上一节介绍的 Redis 基本数据类型,可能会有些疑问,对于 redis 来说,其数据据存储本质都是 []bytes,为什么可以解析出 Int、int64、float等类型的数据呢?
我们以 Float64() 为例进行说明,具体源码如下:
其实 , 返回值助手函数是将 []byte 类型的原始数据,利用strconv.ParseFloat(string(reply), 64)转换成了 float64类型,因此在我们使用过程中返回值助手函数的选择,应该基于业务和实际存储的数据格式为依据 。我们以第一小节的示例为例,看返回值助手函数如何降低我们的工作量,具体如下:
除了使用返回值助手函数对上述固定结构的结果进行解析外,redigo 包还提供了一个 Scan()函数用于解析自定义的复杂数据结构,我们依然以上一个示例进行说明,具体示例如下:
如果返回结果为结构化切片,也可以使用 canSlice() 方法,从而简化 loop 处理的部分,具体示例如下:
通过上述的示例 , 我们介绍了 scan 函数的基本用法,但是细心的同学可能会发现吗,为什么数据写入时,value 的类型为 []int64 但是读取时只能按照 string 类型读取呢 。这是因为 Redis 底层存储的数据本质都是 string 类型,。无论是 HMSET 还是 MSET 最终都只能按照 string 类型读取,因为其本质都是 hash 结构,不同之处仅在于 HMSET 是嵌套的 hash类型 。因此,[]int64 数据在写入阶段,就已经被自动处理为 []byte , 写入 redis 之后,len 和 类型 属性会丢失 。
如果强行按照 []int64解析将出错:
如果 value 必须以结构化的数据存储,那么可以提前对要写入的数据进行编码,例如 json、protobuf 等 , 取出后再进行解码获得原始数据 。
Golang 指针和结构体于c语言相同,go中也有指针和结构体的概念 。指针表示变量的内存地址 , 结构体用来存储同一类型的数据 。
定义一个指针变量,将变量a的地址赋给指针变量p 。这样,指针变量p也就指向了变量a所在的内容空间 。
new 函数返回一个指针变量
fmt.scan() 就是传入一个指针变量 。
两种方法都可以使用 。
以上简要介绍了go语言中的指针和结构体 。
请问sas中scan函数如何使用?scan函数: scan(s,n,"char")表示从字串string中以char为分隔符提取第n个字串 。
功能(function):从字符表达式s中搜取给定的n个单词
语法(syntax)
1、scan(s,n) n为正数时,从字符s末尾提取n个字符
2、scan(s,n) n为负数时,从字符s开始提取n个字符
3、scan(s,n,list-of-delimiters)
如果指定分隔符 , 则只会按照该分隔符提取 。如果不指定,则按照常用的分隔符拆分,默认分隔符为:空格 .(! $ *) ; ^ - / , % | 等之一或组合 。
扩展资料
注意事项:
1、如果缺失指定的生成变量的长度,系统默认长度为200 。
2、如果|n|=0或大于字符s的长度,则该函数返回空格 。
3、用于读入纯字符或者数字,没有表头;
4、如果输入的单一类型的变量 , 例如均是:数值或者均是字符,用scan效率更高 。但其不能读入混合类型的数据 , 也就是在scan()读入的必须同为字符或者同为数值;
5、默认情况下用scan读入的数据生成向量类型(这也就是为什么读入的数据必须是同为字符或者同为数字) 。
c语言中scan()什么意思你要问的是scanf()函数吧
scanf编辑
与printf函数一样,都被定义在头文件stdio.h里,因此在使用scanf函数时要加上#include stdio.h 。它是格式输入函数 , 即按用户指定的格式从键盘上把数据输入到指定的变量之中 。
函数原型编辑int scanf(const char *format,...);
函数 scanf() 是从标准输入流stdio (标准输入设备 , 一般是键盘)中读内容的通用子程序,可以说明的格式读入多个字符 , 并保存在对应地址的变量中 。[1]
其调用形式为: scanf("格式说明字符串",变量地址);变量地址要求有效,并且与格式说明的次序一致
scanf()函数返回成功赋值的数据项数,读到文件末尾出错时则返回EOF 。
如:
scanf("%d %d",a,b);
如果a和b都被成功读入 , 那么scanf的返回值就是2
如果只有a被成功读入,返回值为1
如果a和b都未被成功读入,返回值为0
如果遇到错误或遇到end of file,返回值为EOF 。
且返回值为int型.
例:使用scanf函数输入数据 。
#includestdio.h
int main(void)
{
int a,b,c;
printf("输入a,b,c\n");
scanf("%d%d%d",a,b,c);
printf("a=%d,b=%d,c=%d\n",a,b,c);
fflush(stdin);
return 0;
}
a,b,c中的是地址运算符,a指a在内存中的地址 。scanf的作用是:按照a , b,c的内存地址将输入的数据存到a,b,c中去 。变量a,b,c的地址是在编译连续阶段分配的(存储顺序由编译器决定) 。
这里注意:如果scanf中%d是连着写的如“%d%d%d”,在输入数据时 , 数据之间不可以加逗号,只能是空格或
tab键或者回车键——“2 3 4” 或
“2(按tab)3(按tab)4(按tab)” 。若是“%d,%d,%d”,则在输入数据时需要加“,”,如“2,3,4”.
【go语言scan函数详解 go语言scanf】go语言scan函数详解的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言scanf、go语言scan函数详解的信息别忘了在本站进行查找喔 。

    推荐阅读