- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经被这个问题困扰了一段时间了。假设我有一个如下所示的 C 程序。我希望能够向该程序发送一些字符串并在之后获得控制权。如果我这样做:
--> cat myfile |我的程序
或
--> 回显“0123”|我的程序
或
--> 我的程序 < 我的文件
我得到输出(我的文件包含“0123”)
30 31 32 33
使用 -n 选项会引发段错误
--> echo -n mystring |
--> echo -n mystring | 。/测试
zsh: 完成 echo -n "0123"|
zsh:段错误./test
我也尝试过使用命名管道,但也不起作用。
我希望能够做类似的事情猫我的文件 |我的程序并取回控件,以便我可以键入其他字符。
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 int main (int argc, char *argv[]) {
6 int i = 0, j;
7 unsigned char buf[512];
8 unsigned char x;
9
10 while ((x = getchar()) != '\n') {
11 buf[i] = x;
12 i++;
13 }
14
16 for (j = 0; j < i; j++) {
17 printf("%x ", buf[j]);
18 }
19 printf ( "\n" );
20
21 return EXIT_SUCCESS;
22 } // end of function main
编辑:
下面是我想出的包装。它做了我想要的一切,除了子执行文件的输出没有正确显示。
没有包装器:
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
2+2
4
使用包装器:
$ ./wrapper bc
2+2
enter
4
删除该行
dup2(pipefd[0], 0); // Set the read end of the pipe as stdin.
使子标准输出正确显示,但当然会破坏包装器。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <assert.h>
int main(int argc, char const *argv[]) {
int cpid;
int pipefd[2];
if (pipe(pipefd) == -1) { perror("pipe.\n"); exit(errno); }
cpid = fork();
if (cpid == -1) { perror("fork."); exit(errno); }
if (cpid) {
// Parent --------------------------------------------------------
int buf_size = 8192;
char buf[buf_size];
size_t file;
// Close the unused read end of the pipe.
close(pipefd[0]);
// Leave a bit of time to the child to display its initial input.
sleep(2);
while (1) {
gets(buf);
if (strcmp("enter", buf) == 0) {
write(pipefd[1], "\n", 1);
} else if (-1 != (file = open(buf, O_RDONLY))) {
// Dump the output of the file to the child's stdin.
char c;
while(read(file, &c, 1) != 0) {
switch(c) {
case '\n':
printf("(skipped \\n)");
break;
default:
printf("%c", c);
write(pipefd[1], &c, 1);
};
}
printf("\n");
} else {
// Dump input to the child's stdin, without trailing '\n'.
for (int i = 0; (buf[i] != 0); i++) {
write(pipefd[1], buf + i, 1);
}
}
}
// Wait for the child to exit.
printf("Waiting for child to exit.\n");
wait(NULL);
} else {
// Child ---------------------------------------------------------
// Close the unused write end of the pipe.
close(pipefd[1]);
// Set the read end of the pipe as stdin.
dup2(pipefd[0], 0); // Set the read end of the pipe as stdin.
char** program_arguments = (char**)(argv + 1);
if (execvp(argv[1], program_arguments) < 0) {
perror("execvp.\n");
exit(errno);
}
}
}
最佳答案
如果您无法修改程序的行为,我认为使用命名管道不可能实现此目的。因为本质上命名管道与通过重定向给出标准输入的输出没有什么不同。
我也不认为如果您使用 shell 的管道或重定向属性,这是不可能的,因为在这种情况下总是会向您的程序发送 EOF,并且您不能忽略 EOF,因为您无法修改程序。
一个可能的解决方案是使用包装器。包装器将首先读取准备好的输入,将它们发送到您的程序,准备好的输入完成后,包装器切换到标准输入。实际的程序只是不断消耗输入,它不知道数据的实际来源。
唯一的缺点是,您无法通过管道或重定向提供准备好的输入,您必须提供文件名。 (我不确定命名管道是否有效。)原因很明显,如果您从标准输入向包装器提供准备好的输入,那么包装器也存在同样的问题。通过这种方式,您只需将问题委托(delegate)给包装器,您可以按照您想要的方式设计它。
C 中的可能实现(根据我使用过的类似包装器进行修改,未经过广泛测试):
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
int main(int argc, char * argv[]) {
char c;
char **pargs ;
char buf[20];
int n;
int pipe_fd[2];
int pid;
pargs = argv+2;
if (pipe(pipe_fd) < 0) {
perror("pipe failed");
exit(errno);
}
if ((pid=fork()) < 0) {
perror ("Fork failed");
exit(errno);
}
if (! pid) {
close(pipe_fd[1]);
dup2(pipe_fd[0],0);
close(pipe_fd[0]);
if (execvp(argv[2],pargs) < 0) {
perror("Exec failed");
exit(errno);
}
} else {
size_t filedesc = open(argv[1],O_RDONLY);
while((n = read(filedesc, buf, 100)) > 0)
write (pipe_fd[1], buf, n);
while((n = read(0, buf, 100)) > 0)
write (pipe_fd[1], buf, n);
}
}
您可以使用此包装器运行您的程序:
./wrapper input.txt myprog possible command line arguments
您可以将初始输入放入input.txt
中。
更简单的解决方案是重新打开标准输入。但是,如果您只是尝试像打开文件一样打开它,则它不起作用。您应该打开终端流并将其复制到应用程序的标准输入。您可以使用以下内容来完成此操作(再次使用包装器):
size_t tty = open("/dev/tty",O_RDONLY);
dup2(tty,0);
更不用说第二个解决方案适用于 Linux 并且不可移植。
关于c - 将输入发送到程序并取回控制权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3288483/
所以我使用 PyGame 制作了 Pong,我想使用遗传算法让 AI 学习玩这个游戏。我希望它只知道其桨、球和控件的位置。我只是不知道如何让人工智能自己移动桨。我不想这样做:“如果球在你上方,就向上。
我有包含 4 个子选项卡的 TabControl。 每个选项卡都包含图片框控件。 我需要获取选中的Tab控件的图片框控件。 知道如何实现吗? 最佳答案 也许 var picBox = TabContr
我需要使用 Java 代码控制 Windows XP 的 Windows,我需要单击/键入 windowsXP 给定窗口的特定按钮/文本字段,如何做到这一点有什么想法吗? 我尝试过的方法是:(1) 我
我是一名优秀的程序员,十分优秀!