英文:
golang: read text file line by line of int strings
问题
我正在处理一个包含整数列表的输入文件,它以字符串形式存在。
我选择使用ReadString('\n')方法逐行读取它。
以下是代码示例:
line, error := inputReader.ReadString('\n')
lineStr := string(line)
控制台输出(长度和值):
lineStr %v 4
lineStr %v 10
lineStr 的长度为"4",可能是由于 rune 编码的原因。
然后,我尝试了几种方法将其转换为简单的整数,但都没有成功。
示例1
num, _ := strconv.ParseUint(lineStr, 0, 64)
输出的 num 为 0(应该是 10)。
示例2
num, _ := strconv.Atoi(lineStr)
输出的 num 为 0(应该是 10)。
示例3
num, _ := strconv.Atoi("10")
输出的 num 为 10(正确)。
示例4
num, _ := strconv.ParseUint("10", 0, 64)
输出的 num 为 10(正确)。
字符串字面量是可以正常工作的,但是从文件中读取的字符串却无法正常工作,这是什么问题?
提前感谢您的帮助!
英文:
I am dealing with an input file containing a list of integers as a string
10
..
I have choosen to read it line by line with ReadString('\n') method
The following code
line, error := inputReader.ReadString('\n')
lineStr := string(line)
console output (length and value)
lineStr %v 4
lineStr %v 10
lineStr as a length of "4", maybe because of rune encoding.
Then I have tried several way to convert it to simple integer but with no success.
Ex1
num, _ := strconv.ParseUint(lineStr, 0, 64)
ouputs a num of 0 (should be 10)
Ex2
num, _ := strconv.Atoi(lineStr)
ouputs a num of 0 (should be 10)
Ex3
num, _ := strconv.Atoi("10")
ouputs a num of 10 (ok)
Ex4
num, _ := strconv.ParseUint("10", 0, 64)
ouputs a num of 10 (ok)
string in literal are ok but string from file do not work, what is wrong ?
thanks in advance
答案1
得分: 4
从文档中可以看到:"ReadString 会读取输入直到第一个分隔符出现为止,并返回包含分隔符在内的数据的字符串。"
因此,我建议您使用一个扫描器(scanner),它可以像您期望的那样处理这种情况:
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lineStr := scanner.Text()
num, _ := strconv.Atoi(lineStr)
fmt.Println(lineStr, num)
}
英文:
From the documentation: "ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter."
Because of this, i suggest you use a scanner, which handles this case like you would expect:
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lineStr := scanner.Text()
num, _ := strconv.Atoi(lineStr)
fmt.Println(lineStr, num)
}
答案2
得分: 1
如果你查看ReadString
的文档,你会注意到返回的string
将包括分隔符(在你的情况下是\n
)。
ReadString
会读取输入直到第一个分隔符出现,返回一个包含数据和分隔符的字符串。
由于读取10后行的长度为4,我会假设行是由\r\n
分隔的。最简单的方法是使用其中一个Trim
函数(比如TrimSpace)来移除它。
英文:
If you look at the documentation of ReadString
you will notice that the string
returned will include the delimiter (in your case \n
).
> ReadString reads until the first occurrence of delim in the input,
> returning a string containing the data up to and including the
> delimiter.
And because the length of the line after reading 10 is 4 I would assume that the lines are delimited by \r\n
. The easiest way to remove it is using one of the Trim
functions (like TrimSpace).
答案3
得分: 1
引用bufio.Reader.ReadString的文档(重点在于):
ReadString会读取输入直到第一个分隔符出现为止,返回一个包含数据的字符串,包括分隔符在内。
现在,引用strconv.ParseInt的文档:
ParseInt返回的错误具有具体类型*NumError,并包括err.Num = s。如果s为空或包含无效的数字,err.Err = ErrSyntax,并且返回值为0。
你的问题是ReadString
方法还会返回终止行的\n
字符,而这是ParseInt
函数无效的字符。
你可以使用以下代码片段来检查真正的错误:
i, err := strconv.ParseInt(line, 10, 64)
if err != nil {
switch err.(*strconv.NumError).Err {
case strconv.ErrSyntax:
fmt.Println("语法错误")
case strconv.ErrRange:
fmt.Println("超出范围的值")
}
}
建议:使用strings.TrimSpace
来清理你的输入。
英文:
Citing the documentation of bufio.Reader.ReadString (emphasis mine):
> ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter.
Now, the documentation of strconv.ParseInt
> The errors that ParseInt returns have concrete type *NumError and include err.Num = s. If s is empty or contains invalid digits, err.Err = ErrSyntax and the returned value is 0
Your problem is that the ReadString
method return also the \n
that terminate the line, which is an invalid character for the ParseInt
function.
You can check the real error with the following snippet
i, err := strconv.ParseInt(line, 10, 64)
if err != nil {
switch err.(*strconv.NumError).Err {
case strconv.ErrSyntax:
fmt.Println("syntax error")
case strconv.ErrRange:
fmt.Println("out of range value")
}
}
Advice: use strings.TrimSpace
to clean your input.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论