如何使用 C 和 linux 从用户那里获取键盘输入?
How do I get keyboard inputs from the user using C and linux?
我必须制作一个简短的程序,创建两个子进程,每个子进程从键盘接受一个整数并将它们写入管道,父进程从管道汇总它们并在屏幕上显示总数。
我已经用 scanf() 写了一个,但是它死机了,它没有给我总和。如果可能,我如何让它与 scanf 或任何其他方式一起工作?
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int pipe(int pd[2]);
int main(int argc, char *argv[])
{
int pd[2], sum=0, num=0;
if(pipe(pd) == -1)
for(int i = 0; i < 2; i++)
{
if(fork() == 0)
{
scanf("%d", num);
if(write(pd[1], &num, sizeof(int)) == -1)
printf("Error: Write()");
}
}
for(int j = 0; j < 2; j++)
{
wait(NULL);
if(read(pd[0], &num, sizeof(int)) == -1)
printf("Error: Read()");
sum += num;
}
printf("Total: %d\n", sum);
}
这里有很多问题:
- 你有
if(pipe(pd) == -1)
,我假设你打算有一个错误处理程序作为它的 "then" 子句,但你没有,所以 children 只会产生如果管道出现故障,这基本上与您想要的相反。
- 你有
scanf("%d", num);
。您需要 &num
,因为 num
还不是指针。
- 您需要从 child 个进程中
return
或 exit
,否则它们将进入下一个循环并消耗输出。
只需修复这些问题,就足以使其正常工作:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int pipe(int pd[2]);
int main(int argc, char *argv[])
{
int pd[2], sum=0, num=0;
if(pipe(pd) == -1)
{
perror("pipe");
return 1;
}
for(int i = 0; i < 2; i++)
{
if(fork() == 0)
{
scanf("%d", &num);
if(write(pd[1], &num, sizeof(int)) == -1)
printf("Error: Write()");
return 0;
}
}
for(int j = 0; j < 2; j++)
{
wait(NULL);
if(read(pd[0], &num, sizeof(int)) == -1)
printf("Error: Read()");
sum += num;
}
printf("Total: %d\n", sum);
}
您还应该修复一些其他问题,但它们还不完整 show-stoppers。这是我突然想到的:
- 您无需声明自己的
pipe
原型。来自 unistd.h 的那个很好。
- 您应该处理
fork
或 scanf
失败的情况。
- 您应该处理部分读取和写入。
- 分叉后,您应该在 children 关闭管道的读取端,在 parent 关闭管道的写入端。
- 您应该考虑使用锁来控制读取输入,这样它就可以不依赖于 TTY 线路缓冲来可靠地工作。
我必须制作一个简短的程序,创建两个子进程,每个子进程从键盘接受一个整数并将它们写入管道,父进程从管道汇总它们并在屏幕上显示总数。
我已经用 scanf() 写了一个,但是它死机了,它没有给我总和。如果可能,我如何让它与 scanf 或任何其他方式一起工作?
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int pipe(int pd[2]);
int main(int argc, char *argv[])
{
int pd[2], sum=0, num=0;
if(pipe(pd) == -1)
for(int i = 0; i < 2; i++)
{
if(fork() == 0)
{
scanf("%d", num);
if(write(pd[1], &num, sizeof(int)) == -1)
printf("Error: Write()");
}
}
for(int j = 0; j < 2; j++)
{
wait(NULL);
if(read(pd[0], &num, sizeof(int)) == -1)
printf("Error: Read()");
sum += num;
}
printf("Total: %d\n", sum);
}
这里有很多问题:
- 你有
if(pipe(pd) == -1)
,我假设你打算有一个错误处理程序作为它的 "then" 子句,但你没有,所以 children 只会产生如果管道出现故障,这基本上与您想要的相反。 - 你有
scanf("%d", num);
。您需要&num
,因为num
还不是指针。 - 您需要从 child 个进程中
return
或exit
,否则它们将进入下一个循环并消耗输出。
只需修复这些问题,就足以使其正常工作:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int pipe(int pd[2]);
int main(int argc, char *argv[])
{
int pd[2], sum=0, num=0;
if(pipe(pd) == -1)
{
perror("pipe");
return 1;
}
for(int i = 0; i < 2; i++)
{
if(fork() == 0)
{
scanf("%d", &num);
if(write(pd[1], &num, sizeof(int)) == -1)
printf("Error: Write()");
return 0;
}
}
for(int j = 0; j < 2; j++)
{
wait(NULL);
if(read(pd[0], &num, sizeof(int)) == -1)
printf("Error: Read()");
sum += num;
}
printf("Total: %d\n", sum);
}
您还应该修复一些其他问题,但它们还不完整 show-stoppers。这是我突然想到的:
- 您无需声明自己的
pipe
原型。来自 unistd.h 的那个很好。 - 您应该处理
fork
或scanf
失败的情况。 - 您应该处理部分读取和写入。
- 分叉后,您应该在 children 关闭管道的读取端,在 parent 关闭管道的写入端。
- 您应该考虑使用锁来控制读取输入,这样它就可以不依赖于 TTY 线路缓冲来可靠地工作。