Appending inside a loop repeats the last value in Golang - loops

When trying to append the values of an iteration in go, the function is appending the last iteration 4 times. For example, i'm trying to parse a string containing network cards data into a map, and when iterating it only appends the last one:
Here's the playground link with the code:
https://go.dev/play/p/mKtFvK36PMn
package main
import (
"fmt"
"strings"
)
type Foo struct {
val int
}
func main() {
NetworkJson := "4 NIC(s) Installed.,[01]: Realtek PCIe GbE Family Controller, Connection Name: Ethernet, DHCP Enabled: Yes, DHCP Server: 10.101.10.13, IP address(es), [01]: 10.1.2.62,[02]: VirtualBox Host-Only Ethernet Adapter, Connection Name: VirtualBox Host-Only Network, DHCP Enabled: No, IP address(es), [01]: 192.168.56.1, [02]: fe80::4c17:978a:2c91:8e27,[03]: VMware Virtual Ethernet Adapter for VMnet1, Connection Name: VMware Network Adapter VMnet1, DHCP Enabled: Yes, DHCP Server: 192.168.146.254, IP address(es), [01]: 192.168.146.1, [02]: fe80::88b4:d443:2ab8:59b5,[04]: VMware Virtual Ethernet Adapter for VMnet8, Connection Name: VMware Network Adapter VMnet8, DHCP Enabled: Yes, DHCP Server: 192.168.128.254, IP address(es), [01]: 192.168.128.1, [02]: fe80::a40d:e64:fa9f:e82f"
var IPs []string
var Data []string
var IPMap = make(map[string]string)
var CardMap = make(map[string]interface{})
var CardIP = make(map[string][]map[string]string)
var NetCard = make(map[string][]interface{})
// Faz loop entre as placas de rede
for _, Cards := range strings.Split(string(NetworkJson), ",[") {
// Faz loop entre os dados de cada placa
for _, CardData := range strings.Split(string(Cards), ",") {
// Verifica se dado inicia com espaço em branco
if strings.HasPrefix(CardData, " ") {
// Verifica se dado sem o espaço em branco começa com [
if strings.HasPrefix(strings.TrimSpace(CardData), "[") {
// Pega IPS
IPs = strings.Split(strings.TrimSpace(string(CardData)), ": ")
IPMap[string(IPs[0])] = strings.TrimSpace(string(IPs[1]))
// Se não iniciar com [ verifica se contém :
} else if strings.Contains(CardData, ":") {
// Pega restante dos dados
Data = strings.Split(strings.TrimSpace(string(CardData)), ":")
CardMap[Data[0]] = strings.TrimSpace(Data[1])
}
}
}
if strings.Contains(Cards, "]") {
// Aloca dados
CardMap["Card Name"] = string(strings.SplitN(string(Cards), ",", 2)[0])[5:]
CardIP["IP Adress(es)"] = append(CardIP["IP Adress(es)"], IPMap)
CardMap["IP Adress(es)"] = CardIP["IP Adress(es)"]
CardIP["IP Adress(es)"] = CardIP["IP Adress(es)"][:0]
NetCard["Cards"] = append(NetCard["Cards"], CardMap)
fmt.Println(CardMap)
}
fmt.Println(NetCard["Cards"])
}
}

You are storing everything into the same map variable CardMap and you are using a singular key "Card Name". The append(NetCard["Cards"], CardMap) does not do a deep copy of the CardMap, only a shallow copy is appended and therefore the shallow copy's data is being update on every iteration. Your other variables have the same problem.
Move the variable declaration into the main loop:
var NetCard = make(map[string][]interface{})
// Faz loop entre as placas de rede
for _, Cards := range strings.Split(string(NetworkJson), ",[") {
var IPs []string
var Data []string
var IPMap = make(map[string]string)
var CardMap = make(map[string]interface{})
var CardIP = make(map[string][]map[string]string)
// Faz loop entre os dados de cada placa
for _, CardData := range strings.Split(string(Cards), ",") {
// ...
https://go.dev/play/p/VE_VWOsvsna

Related

Create program Random

i want to randomize this program that recreates a quiz
I tried to add the rand function but I don't know how to proceed
#include <stdio.h>
int main(void) {
int domanda, punti=0;
puts("Quiz sul Riscaldamento Globale\n Otterrai 1 punto per ogni risposta esatta e 0 per ogni risposta sbagliata o non valida\n");
puts("D1) Secondo il tredicesimo Obiettivo di Sviluppo Sostenibile, la minaccia piu' grande allo sviluppo e'/sono:\n");
puts("[1] I cambiamenti climatici\n"
"[2] L'inquinamento \n"
"[3] Lo scioglimento della calotta glaciale polare \n"
"[4] La crescita demografica\n");
scanf("%d", &domanda);
if(domanda == 1){
puts("risposta corretta\n");
punti = punti + 1;
}else{
puts("risposta sbagliata\n");
punti= punti + 0;
}
puts("D2) Il tempo e il clima sono la stessa cosa.");
puts("[1] Vero \n"
"[2] Falso \n");
scanf("%d", &domanda);
if(domanda == 2){
printf("risposta corretta\n");
punti =punti + 1;
}else{
printf("risposta sbagliata\n");
punti= punti + 0;
}
printf("hai fatto un punteggio di %d su 2", punti);
}
to work it works but I don't understand how to add the random if anyone knows how to do it help me thanks.
A rand() function is available in C standard library: man 3 rand. If you want to explore random number generation, check random.org.
As is, your program is not designed to support randomness: Questions and answers are hard-coded. A first step to make it randomizable would be to store them into a variable. For instance (with correct answer always at first position, end of questions identified with NULL, end of answers of a question identified with NULL, maximum of nine answers per question):
struct {
char * question;
char * answers[10];
} qa[] = {
{
"Secondo il tredicesimo Obiettivo di Sviluppo Sostenibile, la minaccia piu",
{
"I cambiamenti climatici",
"L'inquinamento",
"Lo scioglimento della calotta glaciale polare",
"La crescita demografica",
NULL,
}
},
{
"Il tempo e il clima sono la stessa cosa.",
{
"Falso",
"Vero",
NULL,
}
},
{ NULL, NULL }
};
A program using this variable would then count the number of questions, take one randomly, then display the answers randomly and remember what is the display index of the correct one.

Iterate C array struct in Go

package main
//#cgo LDFLAGS: -ldl -lp11
//#include <stdlib.h>
//#include <libp11.h>
import "C"
import (
"log"
"unsafe"
"fmt"
//"runtime"
//"reflect"
)
func main(){
var ctx *C.PKCS11_CTX
ctx = C.PKCS11_CTX_new()
//log.Println(ctx)
cModulePath := C.CString("/home/procondutor/libaetpkss.so.3.0.3930")
defer C.free(unsafe.Pointer(cModulePath))
rc := C.PKCS11_CTX_load(ctx, cModulePath)
if rc < 0 {
log.Println("1 erro rc menor que 0")
return
}
var slots, slot *C.PKCS11_SLOT
var keys *C.PKCS11_KEY
var nslots, nkeys uint
p := unsafe.Pointer(&nslots)
n := unsafe.Pointer(&nkeys)
//log.Println(nkeys)
rc = C.PKCS11_enumerate_slots(ctx, &slots, (*C.uint)(p))
if rc < 0 {
log.Println("2 erro rc menor que 0")
return
}
slot = C.PKCS11_find_token(ctx, slots, C.uint(nslots));
s := C.GoString(slot.manufacturer)
fmt.Printf("%+v\n", s)
cPin := C.CString("2903")
defer C.free(unsafe.Pointer(cPin))
rc = C.PKCS11_login(slot, 0, cPin);
if rc < 0 {
log.Println("3 erro rc menor que 0")
return
}
rc = C.PKCS11_enumerate_keys(slot.token, &keys, (*C.uint)(n));
if rc < 0 {
log.Println("4 erro rc menor que 0")
return
}
My problem is in the PKCS11_enumerate_keys function, in C this function returns a list according to the code below:
static void list_keys(const char *title, const PKCS11_KEY *keys,
const unsigned int nkeys) {
unsigned int i;
printf("\n%s:\n", title);
for (i = 0; i < nkeys; i++)
printf(" * %s key: %s\n",
keys[i].isPrivate ? "Private" : "Public", keys[i].label);
}
But in Go it only returns the first object.
If I try to iterate in Go, I get the following error:
invalid operation: cannot index keys (variable of type *_Ctype_struct_PKCS11_key_st)
I finally got it with the code below:
list_keys := unsafe.Slice(keys, nkeys)
for i := 0; i < int(nkeys); i++ {
z:= C.GoString(slice[i].label)
fmt.Println(z)
}

Problems rendering a json from array struct [duplicate]

This question already has answers here:
JSON and dealing with unexported fields
(2 answers)
Closed 4 years ago.
I doing a simple rest service with gorilla/mux and mysql database
type Carro struct{
Ano int `json:"ano" `
Cor string `json:"cor" `
Nome string`json:"nome" "`
}
type Revenda struct{
carro []Carro
roda string
}
func test(w http.ResponseWriter, r *http.Request) {
var listas []Carro
carA := Carro{1975,"Amarelo","Fusca"}
listas =append(listas,carA)
carB := Carro{1972,"Azul","Fusca"}
listas =append(listas,carB)
revenda := Revenda{carro:listas,roda:"branca"}
json.NewEncoder(w).Encode(revenda)
}
and the return is only
{}
What am I doing wrong?
You are doing wrong inside to create struct Revenda, where you declare fields of this struct with small letter but J Son package wants fields should be exported(variable first letter should be start with capital letter) that's why its not create J Son for this, So try below code I've modified using your previous code.
type Carro struct {
Ano int `json:"ano"`
Cor string `json:"cor"`
Nome string `json:"nome"`
}
type Revenda struct {
Carro []Carro `json:"carro"`
Roda string `json:"roda"`
}
var listas []Carro
carA := Carro{1975, "Amarelo", "Fusca"}
listas = append(listas, carA)
carB := Carro{1972, "Azul", "Fusca"}
listas = append(listas, carB)
revenda := Revenda{Carro: listas, Roda: "branca"}
fmt.Println(revenda)
json.NewEncoder(w).Encode(revenda)

Using SDL-C library, mouse motion bug in simple game

I am trying to make a simple game. I have the following code with which I am placing some images on the screen. I want to make it so that when left click is pressed and I move the mouse, those images are continuously put on the screen (so that the player does not have to click many times over.) I have the following:
SDL_Surface *mur = NULL, *caisse = NULL, *objectif = NULL, *mario = NULL;
SDL_Rect position;
SDL_Event event;
int continuer = 1, clic_gauche = 0, clic_droit = 0;
int objet_actuel = MUR, i = 0, j = 0;
int carte[NB_BLOCS_LARGEUR][NB_BLOCS_HAUTEUR] = {0};
//Chargement des objets et du niveau.
mur = IMG_Load("mur.jpg");
caisse = IMG_Load("caisse.jpg");
objectif = IMG_Load("objectif.png");
mario = IMG_Load("mario_bas.gif");
if(!Charger_Niveau(carte)) //Erreur de chargement du niveau.
exit(EXIT_FAILURE);
while(continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT)
{
carte[event.button.x/TAILLE_BLOC][event.button.y/TAILLE_BLOC] = objet_actuel; //On met l'objet actuellement choisi a l'endroit du clic.
clic_gauche = 1; //On retient le fait que le dernier clic etait un clic gauche.
}
else if (event.button.button = SDL_BUTTON_RIGHT)
{
carte[event.button.x/TAILLE_BLOC][event.button.y/TAILLE_BLOC] = VIDE; //On vide le bloc ou s'est produit le clic droit.
clic_droit = 1; //On retient le fait que le dernier clic etait un clic droit.
}
break;
case SDL_MOUSEBUTTONUP: //On desactive le booleen qui disait qu'un bouton etait enfonce.
if(event.button.button == SDL_BUTTON_LEFT)
clic_gauche = 0;
else if(event.button.button == SDL_BUTTON_RIGHT)
clic_droit = 0;
break;
case SDL_MOUSEMOTION:
if(clic_gauche == 1)
{
carte[event.motion.x / TAILLE_BLOC][event.motion.y / TAILLE_BLOC] == objet_actuel;
}
else if(clic_droit == 1)
{
carte[event.motion.x/TAILLE_BLOC][event.motion.y/TAILLE_BLOC] == VIDE;
}
break;
The loop then continues checking if some keys have been pressed, then I blit all the images that were loaded using the double matrix carte and I refresh the screen. The problem is mouse motion doesn't work. Debugging events is rather difficult...does anyone see an evident problem with the code?
You're not assigning into carte in the SDL_MOUSEMOTION handler, you're comparing.
(Unfortunately, any expression is allowed to be a statement in C, even if it has no effects/side-effects on the program, so the compiler doesn't necessarily help you find these issues.)
Your handler should be:
case SDL_MOUSEMOTION:
if(clic_gauche == 1)
{
carte[event.motion.x / TAILLE_BLOC][event.motion.y / TAILLE_BLOC] = objet_actuel;
}
else if(clic_droit == 1)
{
carte[event.motion.x/TAILLE_BLOC][event.motion.y/TAILLE_BLOC] = VIDE;
}
break;
(Note the single = in each case of the if/else)
Also, the inverse issue affects the handler for SDL_MOUSEBUTTONDOWN where you're assigning to event.button.button rather than comparing its value against the constant SDL_BUTTON_RIGHT.
Note: for this reason, many developers have taken to putting the constant on left-hand side of a comparison, so that the compiler will give you an error if you mistype the operator. E.g.,
else if (SDL_BUTTON_RIGHT == event.button.button)

Use channels to write byte slice to file can't open file correctly

 Hi, I am use udp protocol(must use it) to transfer file, I encountered a problem when receive byte stream and write to file.
As shown below:
type FileInfo struct {
Flen int64
Fname [24]byte
}
type Datapackage struct {
NContent [1000]byte
Finfo FileInfo
Datatype byte
NContentLen int64
}
func main(){
var dp Datapackage
var recvChan = make(chan []byte)
var buf :=new(bytes.Buffer)
p :=make([]byte, 1041) // 1041 is receive package len
ser, _ := net.ListentenUDP("udp", &addr)
for {
_ ,err := ser.Read(p)
buf.Write(p)
binary.Read(buf, binary.BigEndian, &dp)
if dp.Datatype =='A'{
filenamelen := bytes.IndexByte(dp.Finfo.Fname[:], 0)
filename := string(dp.Finfo.Fname[:filenamelen])
fp, err := os.Create(filename)
if err != nil {
fmt.Println(err)
}
go func(fp *os.File){
for {
wn, err := fp.Write(<-recvChan)
if err != nil {
fmt.Println(err)
}
if wn < 1000{
fmt.Println(wn)
break
}
}(fp)
close(recvChan)
fp.Close()
}
} else{
recvChan<-dp.NContent[:dp.NContentLen]
}
// }else{
// wn, err = fp.Write(dp.NContent[:dp.NContentLen])
// if err != nil {
// fmt.Println(err)
// }
// if wn < 1000{
// fp.Close()
// continue
// }
//}
}
}
 now as above , there has two method to write data stream to file , one is usual way that has been Annotations, other is use channels.  but when use channels , get the size of file is rigth ,but can not open (eg exe ,zip )correct ,and if not use channels , the file can open correct , I don't know why?
any help will appreciated.

Resources