dongzhuji1042 2012-02-11 11:58
浏览 94
已采纳

将io字符串转换为int Atoi无效参数

I'm trying to parse a string from WebSockets connection in Go language. I'm implementing both sides of the connection, so the specification of data format is depending only on me.

As this is a simple app (generally for learning purposes), I've come up with ActionId Data, where ActionId is a uint8. BackendHandler is a handler for every request in WebSocket Connection.

Platform information

kuba:~$ echo {$GOARCH,$GOOS,`6g -V`}
amd64 linux 6g version release.r60.3 9516

code:

const ( // Specifies ActionId's
  SabPause = iota
)

func BackendHandler(ws *websocket.Conn) {
  buf := make([]byte, 512)
  _, err := ws.Read(buf)
  if err != nil { panic(err.String()) }
  str := string(buf)
  tmp, _ := strconv.Atoi(str[:0])
  data := str[2:]
  fmt.Println(tmp, data)
  switch tmp {
    case SabPause:
      // Here I get `parsing "2": invalid argument`
      // when passing "0 2" to websocket connection
      minutes, ok := strconv.Atoui(data)
      if ok != nil {
        panic(ok.String())
      }
      PauseSab(uint8(minutes))
    default:
      panic("Unmatched input for BackendHandler")
  }
}

All the output: (note the Println that I used for inspecting)

0 2
panic: parsing "2": invalid argument [recovered]
    panic: runtime error: invalid memory address or nil pointer dereference

I couldn't find the code from which this error is launch, only where the error code is defined (dependent on platform). I'd appreciate general ideas for improving my code, but mainly I just want to solve the conversion problem.

Is this related to my buffer -> string conversion and slice-manipulation(I didn't want to use SplitAfter methods)?

Edit

This code reproduces the problem:

package main

import (
  "strconv"
  "io/ioutil"
)

func main() {
  buf , _ := ioutil.ReadFile("input")
  str := string(buf)
  _, ok := strconv.Atoui(str[2:])
  if ok != nil {
    panic(ok.String())
  }
}

The file input has to contain 0 2 (depending on the file ending, it may look different on other OSes). This code can be fixed by adding the ending index for reslice, this way:

_, ok := strconv.Atoui(str[2:3])
  • 写回答

1条回答 默认 最新

  • duanqiao3608 2012-02-11 15:04
    关注

    You didn't provide a small compilable and runnable program to illustrate your problem. Nor did you provide full and meaningful print diagnostic messages.

    My best guess is that you have a C-style null-terminated string. For example, simplifying your code,

    package main
    
    import (
        "fmt"
        "strconv"
    )
    
    func main() {
        buf := make([]byte, 512)
        buf = []byte("0 2\x00") // test data
        str := string(buf)
        tmp, err := strconv.Atoi(str[:0])
        if err != nil {
            fmt.Println(err)
        }
        data := str[2:]
        fmt.Println("tmp:", tmp)
        fmt.Println("str:", len(str), ";", str, ";", []byte(str))
        fmt.Println("data", len(data), ";", data, ";", []byte(data))
        // Here I get `parsing "2": invalid argument`
        // when passing "0 2" to websocket connection
        minutes, ok := strconv.Atoui(data)
        if ok != nil {
            panic(ok.String())
        }
        _ = minutes
    }
    

    Output:

    parsing "": invalid argument
    tmp: 0
    str: 4 ; 0 2 ; [48 32 50 0]
    data 2 ; 2 ; [50 0]
    panic: parsing "2": invalid argument
    
    runtime.panic+0xac /home/peter/gor/src/pkg/runtime/proc.c:1254
        runtime.panic(0x4492c0, 0xf840002460)
    main.main+0x603 /home/peter/gopath/src/so/temp.go:24
        main.main()
    runtime.mainstart+0xf /home/peter/gor/src/pkg/runtime/amd64/asm.s:78
        runtime.mainstart()
    runtime.goexit /home/peter/gor/src/pkg/runtime/proc.c:246
        runtime.goexit()
    ----- goroutine created by -----
    _rt0_amd64+0xc9 /home/peter/gor/src/pkg/runtime/amd64/asm.s:65
    

    If you add my print diagnostic statements to your code, what do you see?

    Note that your tmp, _ := strconv.Atoi(str[:0]) statement is probably wrong, since str[:0] is equivalent to str[0:0], which is equivalent to the empty string "".

    I suspect that your problem is that you are ignoring the n return value from ws.Read. For example (including diagnostic messages), I would expect,

    buf := make([]byte, 512)
    buf = buf[:cap(buf)]
    n, err := ws.Read(buf)
    if err != nil {
        panic(err.String())
    }
    fmt.Println(len(buf), n)
    buf = buf[:n]
    fmt.Println(len(buf), n)
    

    Also, try using this code to set tmp,

    tmp, err := strconv.Atoi(str[:1])
    if err != nil {
        panic(err.String())
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器