(作业)
这个程序接受用户的一个整数作为输入,并显示斐波纳契数列的那么多个数字(使用在Unix中创建的子进程)。对于我的任务,程序还需要执行错误检查以确保输入是有效的:参数的数量应该是正确的,给定的数量应该是正整数。
我不知道如何验证用户输入的数字不是小数,也不知道如何阻止用户输入由空格分隔的多个参数(例如:1127)。
如果这是一个愚蠢的问题,请原谅我,但这是我第一次使用C。谢谢你能提供的任何帮助!
# include <stdio.h>
# include <sys/types.h>
# include <unistd.h>
# include <sys/wait.h>
int main()
{
int a = 0, b = 1, n = a + b, i; // decalre global variables and initialize some of them
printf("Enter the number of a Fibonacci Sequence:\n"); // print message to the terminal asking user to enter a number
scanf("%d", &i); // (& is used to get the addresss of a variable) scan user input and store at the address of i (i = user input)
if (i <= 0) {
printf("please only enter an integer number greater than 0\n");
return 1;
}
// check number of arguments
// check that a float was not entered
// printf("first (before pid_t): id = not yet declared, parent pid = %d\n", getpid()); // TEST
// the return value from the fork system call:
// for the child, its value is 0. For the parent, it's the actual pid of the child
pid_t id = fork(); // (pid_t integer type that can rep a processes ID) creates a child process from the original and sets id equal to the return value of the fork
// printf("second (after pid_t, in child process): id = %d, pid = %d\n", id, getpid()); // TEST
if (id < 0) { // if id < 0 an error occured
fprintf(stderr, "Fork Failed"); // stderr is the standard error message to print output to terminal. fprintf is the format print
return 1; // retrun 1 to exit the program
}
if (id == 0) // if id == 0 then we know this is the child process
{
//printf("third (in child, after testing id value): child id = %d, pid = %d\n", id, getpid()); // TEST
printf("child: the first %d numbers in the fibonnaci sequence are:\n", i); // print a message with the number entered by the user
if (i == 1) {
printf("%d", 0);
return 0;
}
else {
printf("%d %d", 0, 1);
i -= 2;
}
while (i > 0) {
n = a + b;
printf(" %d", n);
a = b;
b = n;
i--;
}
}
else // if cpu goes back to parnet before child has completed, tell parent to wait until child has completed
{
printf("Parent is waiting for child to complete...\n");
waitpid(id, NULL, 0); // suspends the calling process until the child pricess ends or is stopped. First parameter is the pid to wait for, the others aren't relevant here
printf("\nParent: the child process is done\n");
//printf("fourth (in else clause): id = %d, pid = %d\n", id, getpid()); // TEST
}
return 0; // program has finished and exited without error. Main must return an int
}
2条答案
按热度按时间d5vmydt91#
首先,您可能想要清楚地定义您想要/不想要禁止哪些类型的输入。以下是一张图片,说明了所有这些问题:
对于一个完整的解决方案,对于每一个部分,你必须决定是接受它们是合法的,还是拒绝它们,认为它们是非法的,或者悄悄地忽略它们,认为它们“不在乎”,或者希望它们不会发生。
scanf
可以处理其中的三到四个。strtol
可以处理其中的大部分,或者如果您在兼职时多做一点工作,可以处理几乎所有的工作;或者,如果您在兼职时做更多的工作,则可以处理所有的工作。(我假设您只对十进制或以10为基数的输入感兴趣。如果您想读取十六进制或二进制,您还必须决定是否接受前导的
0x
或0b
。)[免责声明:是的,这基本上是一条延伸的评论,而不是回答。]
42fyovps2#
scanf
返回成功读取和分配的项目数。因此,第一步是检查scanf
的返回值:我们针对
1
进行测试,因为我们尝试读取一项。%d
说明符告诉scanf
跳过任何前导空格,然后一直读到下一个非数字字符。这意味着它将拒绝以非数字开头的输入,如abc
、a23
、.333
等;对于这些输入,它将返回0
,并且不向i
写入任何内容。但是..。
对于像
12.3
这样的输入,它会将12
转换并赋值给i
,并返回1
,将.3
留在输入流中,以扰乱下一次读取。此外,如果您尝试使用
%d
读取另一个输入,它将立即失败,因为.3
中的前导.
;如果您不设法从输入流中删除那个有问题的字符,您将永远不会使用%d
读取它。scanf
是很棒的,当你知道你的输入永远是良好的,这意味着它不是一个很好的交互输入工具。我的首选方法是将输入作为文本读取,然后尝试使用
strtol
/strtoul
(对于整型)或strtod
(对于浮点型)进行转换。快速、肮脏、未经测试的例子: