Golang从文本文件读取数据到结构体的实现方法
Golang从文本文件读取数据到结构体的实现方法 我的结构体:
type GPSDataRow struct {
vehicletype string
route string
schedule int
shift int
busnumber string
lowgrind int
tripsstart int
tripsend int
directionid int
directiontype string
directionname string
}
文件中的数据示例:Autobusai,65,02,1,2350,0,383,388,43576,D>C, 共有11个数据,全部用逗号分隔。 如何用文件中的数据填充我的结构体?文件大约有5000多行。
我尝试这样做:
for scanner.Scan() {
s := strings.Split(scanner.Text(), ",")
if !scanner.Scan() {
break
}
var gpsdataraw GPSDataRow
gpsdataraw.vehicletype, gpsdataraw.route, gpsdataraw.schedule, gpsdataraw.shift, gpsdataraw.busnumber, gpsdataraw.lowgrind, gpsdataraw.tripsstart, gpsdataraw.tripsend, gpsdataraw.directionid, gpsdataraw.directiontype, gpsdataraw.directionname = s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10]
var gpsdata = append(gpsdata, gpsdataraw)
}
但没有结果。
更多关于Golang从文本文件读取数据到结构体的实现方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我认为如果你使用内置库 encoding/csv 来完成这个任务会更简单。
更多关于Golang从文本文件读取数据到结构体的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
大家好,
感谢你们的回复,但在长时间研究这段代码后,我最终成功解析了所有数据并将其添加到结构体和映射中!
再次感谢你们的帮助,期待下次交流!
我过去在编程面试中使用过这个方法。将数据导入矩阵非常有效。
不过仍然面临为结构体生成唯一名称的挑战。
我提出的解决方案是将数据存储在数组中,数组长度与"文件"中的公交车数量相同。虽然不是最优方案,但这是一个开始。
https://play.golang.org/p/ASGnVUEPegD
嗨 @MantasSilanskas 欢迎加入社区!
你尝试过 io/util 的 readFile 函数吗?
https://golang.org/pkg/io/ioutil/#ReadFile
这会将数据添加到变量中
由于文件有多行,我建议先按 \n 分割。
然后你可以按 , 分割。
这样你会得到一个二维矩阵,可以通过循环将数据添加到你的结构体中。
不过,基于以上信息(没有多行文件的情况),以下是我将数据存入结构体的方案:
package main
import (
"fmt"
"log"
"strconv"
"strings"
)
type GPSDataRow struct {
vehicleType string
route string
schedule int
shift int
busNumber string
lowGrind int
tripsStart int
tripsEnd int
directionID int
directionType string
directionName string
}
func main() {
var err error
gps := new(GPSDataRow)
data := "Autobusai,65,02,1,2350,0,383,388,43576,D>C"
dataSlice := strings.Split(data, ",")
for i, v := range dataSlice {
switch i {
case 0:
gps.vehicleType = v
case 1:
gps.route = v
case 2:
gps.schedule, err = strconv.Atoi(v)
if err != nil {
log.Fatal(err)
}
case 3:
gps.shift, err = strconv.Atoi(v)
if err != nil {
log.Fatal(err)
}
case 4:
gps.busNumber = v
case 5:
gps.lowGrind, err = strconv.Atoi(v)
if err != nil {
log.Fatal(err)
}
case 6:
gps.tripsStart, err = strconv.Atoi(v)
if err != nil {
log.Fatal(err)
}
case 7:
gps.tripsEnd, err = strconv.Atoi(v)
if err != nil {
log.Fatal(err)
}
case 8:
gps.directionID, err = strconv.Atoi(v)
if err != nil {
log.Fatal(err)
}
case 9:
gps.directionType = v
case 10:
gps.directionName = v
}
}
fmt.Println(gps.route)
fmt.Println(gps.busNumber)
fmt.Println(gps.directionType)
}
附注:你需要找到为结构体创建多个实例的方法,否则在处理下一行数据时会覆盖前一个实例。
希望这对你有帮助。
你的代码有几个问题需要修正。主要问题是:
- 在循环中调用了两次
scanner.Scan(),这会导致跳过行 - 没有处理字符串到整数的转换
- 切片
gpsdata需要先初始化
以下是修正后的代码:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type GPSDataRow struct {
vehicletype string
route string
schedule int
shift int
busnumber string
lowgrind int
tripsstart int
tripsend int
directionid int
directiontype string
directionname string
}
func main() {
file, err := os.Open("yourfile.txt")
if err != nil {
panic(err)
}
defer file.Close()
var gpsdata []GPSDataRow
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
s := strings.Split(line, ",")
// 确保有足够的字段
if len(s) < 11 {
continue
}
var gpsdataraw GPSDataRow
gpsdataraw.vehicletype = s[0]
gpsdataraw.route = s[1]
// 转换字符串到整数
gpsdataraw.schedule, _ = strconv.Atoi(s[2])
gpsdataraw.shift, _ = strconv.Atoi(s[3])
gpsdataraw.busnumber = s[4]
gpsdataraw.lowgrind, _ = strconv.Atoi(s[5])
gpsdataraw.tripsstart, _ = strconv.Atoi(s[6])
gpsdataraw.tripsend, _ = strconv.Atoi(s[7])
gpsdataraw.directionid, _ = strconv.Atoi(s[8])
gpsdataraw.directiontype = s[9]
gpsdataraw.directionname = s[10]
gpsdata = append(gpsdata, gpsdataraw)
}
if err := scanner.Err(); err != nil {
panic(err)
}
// 验证结果
fmt.Printf("成功读取 %d 行数据\n", len(gpsdata))
if len(gpsdata) > 0 {
fmt.Printf("第一行数据: %+v\n", gpsdata[0])
}
}
更健壮的版本,包含错误处理:
func parseGPSData(filePath string) ([]GPSDataRow, error) {
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
var gpsdata []GPSDataRow
scanner := bufio.NewScanner(file)
lineNumber := 0
for scanner.Scan() {
lineNumber++
line := scanner.Text()
s := strings.Split(line, ",")
if len(s) < 11 {
fmt.Printf("第 %d 行字段不足,跳过\n", lineNumber)
continue
}
var row GPSDataRow
row.vehicletype = s[0]
row.route = s[1]
// 带错误处理的转换
if schedule, err := strconv.Atoi(s[2]); err == nil {
row.schedule = schedule
}
if shift, err := strconv.Atoi(s[3]); err == nil {
row.shift = shift
}
row.busnumber = s[4]
if lowgrind, err := strconv.Atoi(s[5]); err == nil {
row.lowgrind = lowgrind
}
if tripsstart, err := strconv.Atoi(s[6]); err == nil {
row.tripsstart = tripsstart
}
if tripsend, err := strconv.Atoi(s[7]); err == nil {
row.tripsend = tripsend
}
if directionid, err := strconv.Atoi(s[8]); err == nil {
row.directionid = directionid
}
row.directiontype = s[9]
row.directionname = s[10]
gpsdata = append(gpsdata, row)
}
if err := scanner.Err(); err != nil {
return nil, err
}
return gpsdata, nil
}
使用方法:
func main() {
gpsdata, err := parseGPSData("data.txt")
if err != nil {
panic(err)
}
fmt.Printf("成功解析 %d 行GPS数据\n", len(gpsdata))
}
主要修正点:
- 移除了多余的
scanner.Scan()调用 - 添加了字符串到整数的转换
- 添加了错误处理和字段验证
- 确保切片正确初始化

