英文:
Writing to C program using GO but C program doesn't stop at scanf()
问题
在这些代码片段中,Go程序试图向C程序的stdin写入数据。问题在于,当Go循环结束后,C程序会启动一个无限循环。
main.c
#include <stdio.h>
#include <stdlib.h>
int main(){
int age;
char name[8];
for(;;)
{
scanf(" %s : %d\n",&name, &age);
printf("%s : %d\n",name, age);
}
return 0;
}
run/main.go
func main() {
proc := exec.Command("../main")
stdin, err := proc.StdinPipe()
if err != nil {
fmt.Println(err)
}
defer stdin.Close()
proc.Stdout = os.Stdout
proc.Stderr = os.Stderr
fmt.Println("START")
if err = proc.Start(); err != nil {
log.Fatal("An error occured: ", err)
}
for i := 0; i < 500; i++ {
io.WriteString(stdin, fmt.Sprintf("hello : %d\n", i))
//如何在这里等待并读取printf()的输出?
}
//proc.Process.Kill() 在这里杀死proc会太快
fmt.Println("END")
}
当被杀死时,进程无法完成其输出。
输出
START
END
hello : 497
hello : 498
hello : 499
hello : 499
期望输出
START
....
hello : 497
hello : 498
hello : 499
END
英文:
In these snippets the go program tries to write to C program's stdin. The problem is that the c program starts an infinite loop after the go loop finishes.
main.c
#include <stdio.h>
#include <stdlib.h>
int main(){
int age;
char name[8];
for(;;)
{
scanf(" %s : %d\n",&name, &age);
printf("%s : %d\n",name, age);
}
return 0;
}
run/main.go
func main() {
proc := exec.Command("../main")
stdin, err := proc.StdinPipe()
if err != nil {
fmt.Println(err)
}
defer stdin.Close()
proc.Stdout = os.Stdout
proc.Stderr = os.Stderr
fmt.Println("START")
if err = proc.Start(); err != nil {
log.Fatal("An error occured: ", err)
}
for i := 0; i < 500; i++ {
io.WriteString(stdin, fmt.Sprintf("hello : %d\n", i))
//How to wait here and read from printf()?
}
//proc.Process.Kill() Here proc gets killed too fast
fmt.Println("END")
}
When killed, process doesn't complete it's output
Output
START
END
hello : 497
hello : 498
hello : 499
hello : 499
Output Expected
START
....
hello : 497
hello : 498
hello : 499
END
答案1
得分: 0
在阅读了评论并进行了更多搜索后,我解决了问题。
在C程序中,我从scanf()中删除了\n,并在printf之后添加了fflush(stdout)。
根据这个页面,我将它们更改为以下内容:
int main(){
int age;
char name[8];
int ret;
for(;;)
{
ret= scanf("%s : %d",&name, &age);
if (ret == -1) {
break;
}
printf("%s : %d\n",name, age);
fflush(stdout);
}
return 0;
}
func main(){
proc := exec.Command("../main")
stdin, err := proc.StdinPipe()
if err != nil {
fmt.Println(err)
}
reader, err := proc.StdoutPipe()
if err != nil {
fmt.Println(err)
return
}
scanner := bufio.NewScanner(reader)
resp := make(chan string)
go func() {
for scanner.Scan() {
resp <- scanner.Text()
}
}()
err = proc.Start()
if err != nil {
fmt.Fprintln(err)
return
}
fmt.Println("START")
for i := 0; i < 500; i++ {
io.WriteString(stdin, fmt.Sprintf("hello : %d\n", i))
v := <-resp
print(v+"\n")
}
err = proc.Process.Kill()
if err != nil {
fmt.Fprintln(err)
return
}
fmt.Println("END")
}
英文:
After reading the comments and few more searching I have worked it out.
On C program I removed \n from scanf() and added fflush(stdout) after printf.
According to this page I changed them to these:
int main(){
int age;
char name[8];
int ret;
for(;;)
{
ret= scanf("%s : %d",&name, &age);
if (ret == -1) {
break;
}
printf("%s : %d\n",name, age);
fflush(stdout);
}
return 0;
}
func main(){
proc := exec.Command("../main")
stdin, err := proc.StdinPipe()
if err != nil {
fmt.Println(err)
}
reader, err := proc.StdoutPipe()
if err != nil {
fmt.Println(err)
return
}
scanner := bufio.NewScanner(reader)
resp := make(chan string)
go func() {
for scanner.Scan() {
resp <- scanner.Text()
}
}()
err = proc.Start()
if err != nil {
fmt.Fprintln(err)
return
}
fmt.Println("START")
for i := 0; i < 500; i++ {
io.WriteString(stdin, fmt.Sprintf("hello : %d\n", i))
v := <-resp
print(v+"\n")
}
err = proc.Process.Kill()
if err != nil {
fmt.Fprintln(err)
return
}
fmt.Println("END")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论