Golang中Printf函数在for循环中无法正常工作的问题
Golang中Printf函数在for循环中无法正常工作的问题 我正在用Go语言编写一个Brainf**k解释器。 但我的程序中有一个奇怪的bug,我找不到原因。
func Execute(code string) {
program, err := Compile(code)
if program == nil {
panic(err)
}
for i := 0; i < len(program); i++ {
e := program[i]
switch e[0] {
case dec_ptr:
if ptr <= 0 {
ptr = mem_size - 1
break
}
ptr--
case inc_ptr:
if ptr >= mem_size-1 {
ptr = 0
break
}
ptr++
case decrease:
if memory[ptr] <= 0 {
memory[ptr] = 255
break
}
memory[ptr]--
case increase:
if memory[ptr] >= 255 {
memory[ptr] = 0
break
}
memory[ptr]++
case output:
fmt.Printf("%s", string(memory[ptr]))
case input:
case loop_start:
if memory[ptr] == 0 {
i = e[1] - 1
}
case loop_end:
if memory[ptr] != 0 {
i = e[1] - 1
}
}
// fmt.Printf("%d, %d, %d, %d, %d\n", memory[0], memory[1], memory[2], memory[3], memory[4])
}
}
以上是我的程序中存在bug的主要函数。
当我使用 go run . 或 go build, ./<program-name> 来运行我的程序时,它不会打印结果。
但是当我使用VS Code的调试工具来运行它时,它会打印结果。
我找不到原因!请帮帮我!
以下是我用来测试的BF代码,这个bug在其他BF代码中没有出现。
[-] H
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++ .
[-] e
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ + .
[-] l 2
>++
[<
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
此文件已被截断。显示原文
更多关于Golang中Printf函数在for循环中无法正常工作的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang中Printf函数在for循环中无法正常工作的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题在于标准输出缓冲。fmt.Printf 在默认情况下是行缓冲的,当输出不是完整行时,内容可能不会立即刷新到终端。
在调试器中运行时,通常会强制刷新输出缓冲,所以能看到结果。但在普通执行时,输出被缓冲了,程序结束时可能没有正确刷新。
解决方案是显式刷新输出,或者使用无缓冲输出。以下是修改后的代码:
case output:
fmt.Printf("%s", string(memory[ptr]))
// 显式刷新标准输出
fmt.Print()
或者使用 os.Stdout 直接写入:
case output:
os.Stdout.Write([]byte{memory[ptr]})
完整修改示例:
import (
"fmt"
"os"
)
func Execute(code string) {
program, err := Compile(code)
if program == nil {
panic(err)
}
for i := 0; i < len(program); i++ {
e := program[i]
switch e[0] {
case dec_ptr:
if ptr <= 0 {
ptr = mem_size - 1
break
}
ptr--
case inc_ptr:
if ptr >= mem_size-1 {
ptr = 0
break
}
ptr++
case decrease:
if memory[ptr] <= 0 {
memory[ptr] = 255
break
}
memory[ptr]--
case increase:
if memory[ptr] >= 255 {
memory[ptr] = 0
break
}
memory[ptr]++
case output:
// 方法1: 使用fmt.Printf并刷新
fmt.Printf("%s", string(memory[ptr]))
fmt.Print() // 强制刷新
// 或者方法2: 直接写入os.Stdout
// os.Stdout.Write([]byte{memory[ptr]})
case input:
case loop_start:
if memory[ptr] == 0 {
i = e[1] - 1
}
case loop_end:
if memory[ptr] != 0 {
i = e[1] - 1
}
}
}
// 程序结束时确保所有输出都被刷新
os.Stdout.Sync()
}
另一个选择是在程序开始时设置无缓冲输出:
func init() {
// 设置标准输出为无缓冲
buf := bufio.NewWriter(os.Stdout)
os.Stdout = &unbufferedWriter{w: buf}
}
type unbufferedWriter struct {
w *bufio.Writer
}
func (uw *unbufferedWriter) Write(p []byte) (n int, err error) {
n, err = uw.w.Write(p)
uw.w.Flush()
return n, err
}
这个问题在Brainfuck解释器中特别明显,因为Brainfuck程序通常逐个字符输出,而不是按行输出。

