哦, 这该死的txt回车符~

  • 今天的golang学习被txt中的回车符困扰了半个小时, 最后才傻傻的发现, mark一下

问题描述

我想从两个文件 test1.txttest2.txt中分别按行读取字符串, 然后统计字符串的出现次数.
两文件内容分别如下, 是我手动键入的:

test1
test2
test2
test1
  • 按照逻辑来说, 最终统计结果是, test1test2都分别出现两次,
  • 但是结果却并不如我所想, map中有四个字符串, 打印出来是
test1
test1
test2
test2

明明它们都一样, 怎么统计的呀, 难道是golang的map有问题???

  • 遇事先想自己的问题, 不能怀疑语言, 不能怀疑编译器, 这是从百度面试官那里学到的
    我的代码如下
package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

func main()  {
	//fmt.Println("dup3,test filename")
	counts := make(map[string]int)
	filenames := []string{"data\\test1.txt","data\\test2.txt"}
	for _,fileName := range filenames{
		data, err := ioutil.ReadFile(fileName) // 返回字节数组, 以及错误类型
		//fmt.Println(data)
		if err != nil{
			fmt.Fprintf(os.Stderr, "dup3: %v\n", err)
			continue
		}
		for _,str := range strings.Split(string(data),"\n"){
			counts[str]++
		}
	}

	for line,cnt := range counts{
		if cnt >1 {
			fmt.Printf("%d\t%s\n",cnt,line)
		}
	}
}

问题分析与解决

  • 为什么test1test1不同呢, 它们明明是同一个字符串
  • 经过思考, 我猜到了答案, 回车符, 然后就是验证
  • 原因在于, readFile是读入的字节切片, 而不是按行读入
  • 我们将readFile读取到的字节切片直接打印, 可以得到如下结果
[116 101 115 116 49 13 10 116 101 115 116 50]
[116 101 115 116 50 13 10 116 101 115 116 49]
  • 这是因为我在敲txt的时候, 习惯性敲了回车键, ascll码13对应的就是\r, 即回车, 而10对应的就是换行
  • 所以原因是因为我手敲的文件内容, 其中为了换行, 用了回车符, 而换行本身又是\n, 所以在上面我们用/n来进行split会产生长度为6和长度为5的字符串, 分别是test1\rtest1,test2\rtest2, 自然又不一样了, 然后打印出来, 因为经过了系统函数的格式化, 删除了回车符, 所以看起来都一样, 于是搞不清是哪出了问题
  • 这个问题只是因为我们手敲导致, 如果是代码写入txt, 那么一般都不会使用回车符+换行符, 而是直接使用换行符, 则没有本文的问题出现
  • 解决方法为, 将splitsep换成\r\n即可
  • 然后就能正确打印结果啦
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值