user3125693
user3125693

Reputation: 950

Go CSV file parsing

I'm trying to do a really simple parse of a CSV file but for some reason, it only reads the very last row of the file.

I've tried using reader.ReadAll()

package main

import (
     "encoding/csv"
     "fmt"
     "os"
)

func main() {

     csvfile, err := os.Open("somecsvfile.csv")

     if err != nil {
             fmt.Println(err)
             return
     }

     defer csvfile.Close()

     reader := csv.NewReader(csvfile)

     reader.FieldsPerRecord = -1 // see the Reader struct information below

     rawCSVdata, err := reader.ReadAll()

     if err != nil {
             fmt.Println(err)
             os.Exit(1)
     }

     // sanity check, display to standard output
     for _, each := range rawCSVdata {
             fmt.Printf("email : %s and timestamp : %s\n", each[0], each[1])
     }
}

And I've tried just a simple reader.Read() from this snippet

for {
    row, err := csvr.Read()
    if err != nil {
        if err == io.EOF {
            err = nil
        }
    }
    fmt.Println(row)
}

Both of these snippets I found online which seem really straightforward. The CSV package seems to describe exactly what I want as well (ReadAll() should read the entire CSV into a slice of string slice).

The CSV files seem completely fine too. Downloading one online I have the below (each line is a separate entry except for first row).
What am I doing wrong?

street,city,zip,state,beds,baths,sq__ft,type,sale_date,price,latitude,longitude
3526 HIGH ST,SACRAMENTO,95838,CA,2,1,836,Residential,Wed May 21 00:00:00 EDT 2008,59222,38.631913,-121.434879
51 OMAHA CT,SACRAMENTO,95823,CA,3,1,1167,Residential,Wed May 21 00:00:00 EDT 2008,68212,38.478902,-121.431028

EDIT:
I think I found out what's going wrong. In the code below, if I change fmt.Print(col) to fmt.Println(col) I end up printing every column of every row. If I leave it as fmt.Print(col), I only print 1 row. Does anyone know why this happens?
I thought Print and Println() acted the same way, just println() adds a new line?

     // sanity check, display to standard output
     for _, row := range rawCSVdata {
            for _, col := range row {
                    _,err := fmt.Print(col)
                    if err != nil {
                            fmt.Println(err)
                    }
            }
            fmt.Println("")
     }

Upvotes: 0

Views: 2792

Answers (1)

user6169399
user6169399

Reputation:

When using fmt.Print(col) inside for loop, you need to add space after your data e.g. fmt.Print(i, " ") (try on The Go Playground):

package main

import "fmt"    

func main() {
    for i := 0; i < 10; i++ {
        fmt.Print(i)
    }
}

output:

0123456789

This works fine, try it on The Go Playground:

package main

import (
    "encoding/csv"
    "fmt"
    "strings"
)

func main() {
    reader := csv.NewReader(strings.NewReader(str))
    reader.TrimLeadingSpace = true
    reader.FieldsPerRecord = -1 // see the Reader struct information below
    rawCSVdata, err := reader.ReadAll()
    if err != nil {
        panic(err)
    }
    for _, each := range rawCSVdata {
        //fmt.Println(each)
        fmt.Printf("%-15q %-150q \n", each[0], each[1])
    }
    fmt.Println()
    for _, row := range rawCSVdata {
        for _, col := range row {
            //fmt.Print(col)
            fmt.Printf("%30q ", col)
        }
        fmt.Println("")
    }
}

var str = `street,city,zip,state,beds,baths,sq__ft,type,sale_date,price,latitude,longitude
    3526 HIGH ST,SACRAMENTO,95838,CA,2,1,836,Residential,Wed May 21 00:00:00 EDT 2008,59222,38.631913,-121.434879
    51 OMAHA CT,SACRAMENTO,95823,CA,3,1,1167,Residential,Wed May 21 00:00:00 EDT 2008,68212,38.478902,-121.431028`

output:

"street"        "city"                                                                                                                                                 
"3526 HIGH ST"  "SACRAMENTO"                                                                                                                                           
"51 OMAHA CT"   "SACRAMENTO"                                                                                                                                           

                      "street"                         "city"                          "zip"                        "state"                         "beds"                        "baths"                       "sq__ft"                         "type"                    "sale_date"                        "price"                     "latitude"                    "longitude" 
                "3526 HIGH ST"                   "SACRAMENTO"                        "95838"                           "CA"                            "2"                            "1"                          "836"                  "Residential" "Wed May 21 00:00:00 EDT 2008"                        "59222"                    "38.631913"                  "-121.434879" 
                 "51 OMAHA CT"                   "SACRAMENTO"                        "95823"                           "CA"                            "3"                            "1"                         "1167"                  "Residential" "Wed May 21 00:00:00 EDT 2008"                        "68212"                    "38.478902"                  "-121.431028" 

Upvotes: 1

Related Questions