我正在学习C语言,我的程序有问题。
所以,我有一个名为TEST
这个程序应该允许我用argv[]
或使用输入流$ TEST < argsTest.json
来读取参数。
argsTest.json :
{
"a" = 2,
"b" = 3
}
为了简化我的问题,我将使用这个简单的程序:
Struct {
int a;
int b;
} number;
int main(int argc, char **argv) {
json_t * root;
struct number numbers;
int c = 0, i = 0 , result;
char str[1024]; // I'm not using malloc just to simplify my question
// default values
numbers.a = 0;
number.b = 0;
if (argc == 1 && !feof(stdin)) {
while((c = fgetc(stdin)) != EOF) {
str[i]=c;
++i;
}
str[i] = ' ';
.... // code that use jansson library to extract value
/** let's suppose we have extracted the two value int json_a
* and int json_b.
*/
numbers.a = json_a;
numbers.b = json_b;
} else if (argc == 3) {
scanf("%d", numbers.a);
scanf("%d", numbers.b);
}
result = numbers.a + number.b;
printf("%dn", result);
return 0;
}
因此,我正在尝试实现三种行为:
-
$ TEST
它应该显示0
(我们使用默认值(。 -
$ TEST < argsTest.json
显示5
。 -
$ TEST 4 3
显示7
。
我的问题是,如果语句if (argc == 1 && !feof(stdin))
,实际上 $ TEST
和 $ TEST < argsTest.json
argc == 1
具有相同的语句,因此运行时$ TEST
它错误,因为他输入了第一个条件。
我想要一个 if 语句来检查输入流是否为空并且具有0
参数,因此我可以在不进入 if 语句的情况下实现第一种情况。
谢谢。
一般思路是
- 首先检查
argc
以查看是否应使用argv
中的值 - 检查终端是否交互
- 如果是,则只需打印 0
- 如果它不是交互式的,那么您可以从
stdin
中读取
问题是没有便携式方法来检查stdin
是否是交互式的。但是,在 POSIX 系统上,您可以使用 isatty
函数,如本问题中所述。
因此,假设您在 POSIX 系统上,代码如下所示:
int main(int argc, char *argv[])
{
struct number numbers;
if (argc == 3)
{
if (sscanf(argv[1], "%d", &numbers.a) == 1 && sscanf(argv[2], "%d", &numbers.b) == 1)
printf("From argv the answer is %dn", numbers.a + numbers.b);
else
printf("Bad strings in argvn");
}
else if (isatty(STDIN_FILENO))
{
printf("Nothing in argv or on stdin, so the answer is 0n");
}
else
{
if (scanf("%d%d", &numbers.a, &numbers.b) == 2)
printf("From stdin the answer is %dn", numbers.a + numbers.b);
else
printf("Found junk on stdinn");
}
}