问题
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:
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:
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:
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.
来源:https://stackoverflow.com/questions/28983831/golang-read-text-file-line-by-line-of-int-strings