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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.