由于某种原因,如果我写的不是"a+bi+c+di"而是"a+bi*c+di",我的argc
参数从4变为6,我不知道为什么。发生了什么,我该如何解决?
谢谢
#include <stdio.h>
#include <string.h>
#define FORMATLOG "Invalid Input. Required format: <a+bi> <operator> <c+di>"
#define INPUTLOG "Error: Trying to operate with different sets of numbers"
enum { true, false };
typedef struct {
double realp, imagp;
} Complex;
int checkIfComplex(char *exp) {
unsigned int i = 1;
if(exp[strlen(exp) - 1] == 'i')
while(exp[i] != ' ') {
if(exp[i] == '+' || exp[i] == '-')
return true;
i++;
}
return false;
}
Complex parseComplex(char *exp) {
Complex number;
sscanf(exp, "%lf + %lfi", &number.realp, &number.imagp);
return number;
}
int main(int argc, char **argv) {
printf("%d", argc);
if(argc != 4) {
puts(FORMATLOG);
return false;
}
if(argv[2][0] != '%')
if(checkIfComplex(argv[1]) || checkIfComplex(argv[3])) {
puts(INPUTLOG);
return false;
}
Complex result,
fterm = parseComplex(argv[1]),
sterm = parseComplex(argv[3]);
switch(argv[2][0]) {
case '+':
result.realp = fterm.realp + sterm.realp;
result.imagp = fterm.imagp + sterm.imagp;
break;
case '-':
result.realp = fterm.realp - sterm.realp;
result.imagp = fterm.imagp - sterm.imagp;
break;
case '*': case 'x':
result.realp = fterm.realp * sterm.realp;
result.imagp = fterm.realp * sterm.imagp
+ fterm.imagp * sterm.realp
- fterm.imagp * sterm.imagp;
default:
puts(FORMATLOG);
return false;
}
fprintf(stdout, ">> %g + %gin", result.realp, result.imagp);
return true;
}
在传递给应用程序之前,'*'似乎被视为通配符并由shell进行扩展。例如,
int main(int argc, char** argv)
{
int ndx;
printf("%dn", argc);
for(ndx = 0; ndx < argc; ndx++)
{
printf("argument %d is %sn", ndx, argv[ndx]);
}
return 0;
}
生成以下输出(在Ubuntu主机上,使用gcc-4.8作为编译器):
******@ubuntu:~/junk$ ./complex a+bi * c+di
6
argument 0 is ./complex
argument 1 is a+bi
argument 2 is complex
argument 3 is complex.c
argument 4 is complex.c~
argument 5 is c+di
我可以看到两种解决你问题的方法:
(1) 像这样逃离*
:
xxxxxx@ubuntu:~/junk$ ./complex a+bi * c+di
4
argument 0 is ./complex
argument 1 is a+bi
argument 2 is *
argument 3 is c+di
这里的问题是,你将不得不逃离任何具有特殊意义的符号,而写*似乎并不自然。此外,我不确定它的便携性如何,因为外壳使用了不同的逃生符。
(2) 引用整个表达式如下:
xxxxxx@ubuntu:~/junk$ ./complex "a+bi * c+di"
2
argument 0 is ./complex
argument 1 is a+bi * c+di
至少在这里,用户可以用普通形式编写表达式,他们只需要记住引用它。此外,这还提供了一些保护,防止用户在表达式中添加额外的空格,即a + bi * c+di
。这里的问题是,使用需要记住引用表达式,并且需要进行更多的解析来提取这两个术语。