0

I have a array/struct that constantly printing

for{
        results, errz := client.ReadHoldingRegisters(0, 3)
        if errz != nil {
            fmt.Printf("%v\n", errz)
        }

        fmt.Printf("results %v\n", results)
    }

Printing output will be like this.

[0 0 0 0 0 0]
[0 0 0 0 0 0]
[0 0 0 0 0 0]

How do i add it into append it into json format? I'm very new to GOLANG. I printed the type out

fmt.Printf("var1 = %T\n", results) 

Results is []uint8 I need save as int on json format.

12
  • when you mean json, would turning [0 0 0 0 0 0] into [0, 0, 0, 0, 0, 0] be enough for you? Commented Jan 19, 2021 at 0:38
  • Yes. that will be suffice. Thank you. Commented Jan 19, 2021 at 0:40
  • @brunoff Something like this { "data": { "1": "0,0,0,0,0,0" } } Commented Jan 19, 2021 at 0:43
  • j := fmt.Sprintf("%#v",*results); j = "{ \"data\": { \"1\": \""+j[7:len(j)-1]+"\"} }" // j will hold your json in the format you commented right now. too simple and without error checking, but at least works for this simple situation Commented Jan 19, 2021 at 1:01
  • I added your two lines just after printf results. and got this error invalid indirect of results (type []byte) Commented Jan 19, 2021 at 1:12

2 Answers 2

1

Different approaches to solve to problem.

The simple (and safe) approach:

// import "fmt" "strings"
j := fmt.Sprintf(`{"data":{"1":%s}}`, strings.Join(strings.Fields(fmt.Sprintf("%d", results)), ","))

Previously in the comments I have made this lazier approach, without strings, but it is less safe:

// import "fmt"
j := fmt.Sprintf("%#v",*results); j = "{ \"data\": { \"1\": \""+j[7:len(j)-1]+"\"} }"
// works when the array size is between 1 and 9, above this, the "7" must increase

Now using the native golang json infrastructure.

Here, an example, using hard-coded results := []uint{0, 0, 0, 0, 0, 0}

package main

import (
    "encoding/json"
    "io/ioutil"
    "log"
)
type d struct {
    Data o `json:"data"`
}
type o struct {
    One []uint `json:"1"`
}
func main() {
    results := []uint{0, 0, 0, 0, 0, 0}
    j, _ := json.Marshal(&d{Data:o{One:results}})
    err := ioutil.WriteFile("output.json", []byte(j), 0777) // i can't test here I don't know if []byte(j) or []byte(string(j)) should be used
    if err != nil {
        log.Fatal(err)
    }
}

But once your array is of uint8 instead of uint and golang's json encode []uint8 (which is the same as []byte) as base64 strings, we have to implement our own Marshaller to avoid this behaviour by implementing MarshalJSON, in the same way as seen on How to marshal a byte/uint8 array as json array in Go?.

package main

import (
    "encoding/json"
    "io/ioutil"
    "strings"
    "log"
    "fmt"
)
type d struct {
    Data o `json:"data"`
}
type o struct {
    One []uint8 `json:"1"`
}
func (t *o) MarshalJSON() ([]byte, error) {
    var one string
    if t.One == nil {
        one = "null"
    } else {
        one = strings.Join(strings.Fields(fmt.Sprintf("%d", t.One)), ",")
    }
    jsonresult := fmt.Sprintf(`{"1":%s}`, one)
    return []byte(jsonresult), nil
}
func main() {
    results := []uint8{0, 0, 0, 0, 0, 0}
    j, _ := json.Marshal(&d{Data:o{One:results}})
    err := ioutil.WriteFile("output.json", []byte(j), 0777) // i can't test here I don't know if []byte(j) or []byte(string(j)) should be used
    if err != nil {
        log.Fatal(err)
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much. One last error i think... cannot use results (type []byte) as type []uint in field value I change the o struct to One []uint to []byte and the string i write in json is always AAAAA.. instead of value
ok, to workaround this we have to implement our own marshaller. but once we are implementing our own marshaller, i believe it is better to use the simplier approach, without golang's native json support. i left all different solutions in the answer.
sorry to bother you again, is it possible to append to the json instead of overwriting it? do i have to redefined the struct array once again?
0

I used to have the same problem, so I fixed it with below code:

// sample-entity.go
type Sample struct {
    sample int `db:"sample" json:"sample"`,
}

writing to json file

// it will create a new file if exists already too
jsonFile, jsonFileError := os.Create(directory + "/[file_name].json")
jsonToWrite := []Sample{
    {
         sample: 1
    }      
}

if jsonFileError != nil {
    panic(jsonFileError)
}
defer jsonFile.Close()

// write in json file
jsonWriter := json.NewEncoder(jsonFile)
jsonWriter.Encode(jsonFile)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.