Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中区分作为字符的单个数字和多个数字?_C_Arrays_Char_Int_Arithmetic Expressions - Fatal编程技术网

如何在C中区分作为字符的单个数字和多个数字?

如何在C中区分作为字符的单个数字和多个数字?,c,arrays,char,int,arithmetic-expressions,C,Arrays,Char,Int,Arithmetic Expressions,所以,我从stdin读取输入,我必须从中计算算术。例如,我可能会得到: 3+4 4+3 7+9 然后将其放入一个字符数组中,如下所示: {3+4;4+3;7+9} 我想创建一个程序,该程序将接受此输入并返回: {7;7;16} 因为这是C中的stdin,所以每个元素都是char类型。 我创建了以下代码来处理这样的数组并返回正确的结果: char *int2string(int i, char *s) { sprintf(s, "%d", i); return s; }

所以,我从stdin读取输入,我必须从中计算算术。例如,我可能会得到:

3+4
4+3
7+9
然后将其放入一个字符数组中,如下所示:

{3+4;4+3;7+9}
我想创建一个程序,该程序将接受此输入并返回:

{7;7;16}
因为这是C中的stdin,所以每个元素都是char类型。 我创建了以下代码来处理这样的数组并返回正确的结果:

char *int2string(int i, char *s)
{
    sprintf(s, "%d", i);
    return s;
}

        bufferlen = strlen(buffer);
        int result;
        for (i = 0; i < bufferlen; i++)
        {
            if (isNumeric(buffer[i]))
            {
                value1 = atoi(&buffer[i]);
                if (buffer[i + 1] == '+')
                {
                    if (isNumeric(buffer[i + 2]))
                    {
                        value2 = atoi(&buffer[i + 2]);
                        result = value1 + value2;
                        printf("This is the result: %d\n", result);
                        int2string(result, &buffer[i]);
                        for (int k = i + 1; k < bufferlen; k++)
                        {
                            buffer[k] = buffer[k + 2];
                        }
                        //bufferlen = bufferlen - 2;
                    }
                }
            }
        }
我的代码返回以下内容:

This is the result: 26
322;

我相信这是因为我的代码一次只能读取一个字符,无法区分单个数字和由多个数字组成的数字。有什么办法可以解决这个问题吗?

您可以使用
sscanf
获取运算符和任意数字。您可以按如下方式使用它:

int sum, len;
sscanf(buffer, "%d%n", &sum, &len); // get the first number

int number;
char op;

buffer += len;

// then pattern is: "operation""number"
while(sscanf(buffer, "%c%d", &op, &number) == 2) // while you can scan both operation and number
{
    if (op == '+')
        sum += number;
    else if (op == '-')
        sum -= number;
    ...
}

关于sscanf的更多信息。

我认为,你的问题是,你正在做类似的事情

value1 = atoi(&buffer[i]);
if (buffer[i + 1] == '+')
    ...
char *endp;
value1 = strtol(p, &endp, 10);
p = endp;
if (*p == '+')
    ...
在这个片段中,索引
i
指向
缓冲区中当前正在解析的点。您认为(并且正确地认为)
i
“指向”一个或多个数字字符中的第一个。您可以调用
atoi
将这些数字转换为实际整数。到目前为止还不错。但是,然后测试
buffer[i+1]
以查看数字后面是否有运算符字符。这就是错误的假设产生的地方,即数字总是一位数长。这就是为了正确处理多位数数字需要解决的问题

我认为,解决这个问题的最佳方法是使用
strtol
而不是
atoi
atoi
strtol
之间最明显的区别在于
strtol
告诉您它走了多远,使用了多少位数。它通过向您返回指向它未使用的第一个字符的指针来实现这一点

这意味着,要使用strtol,您必须显式地使用指针。如果你用指针的话会容易得多

char *p;
单步执行
缓冲区
,而不是索引
i
。但是你可以这样说

value1 = atoi(&buffer[i]);
if (buffer[i + 1] == '+')
    ...
char *endp;
value1 = strtol(p, &endp, 10);
p = endp;
if (*p == '+')
    ...
其工作方式是,
strtol
endp
设置为指向它未使用的第一个字符。这就是您想要继续解析的地方,因此您将
p
设置为
endp
并继续


这里实际发生的是
strtol
接受指向指针的指针。如果你还不习惯使用指针,你可能真的还没有准备好考虑指向指针的指针,但是相信我,这是有效的。

我想我应该澄清一下,输入是从stdin获取的,并自动放入如下字符数组:
{3+4;5+4;34+22}
我必须获取这个数组并计算算术,返回这样的数组:
{7;9;56}
这无关紧要。对于char数组的每个元素,执行我提供的解决方案。您是否考虑过使用strtok
或编写一个实际的语法来与lexer和parser一起使用?不,它实际上没有那么复杂。尝试
if(sscanf(s),%d+%d,&a,&b)==2)作为测试,看看输入是否是一个加法。“我必须计算算术”是含糊不清的。必须检测多少算术?谢谢您的帮助。我会尝试使用这个策略,如果我成功了会通知你。所以,我知道如何使用strtol。然而,我真的不明白如何使用它来迭代缓冲区?我也许可以使用while循环,但我不知道条件是什么。@bugg98基本思想是:(a)将
inti
更改为
char*p
,(b)将
for(I=0;I
更改为
for(p=buffer;p
,(c)更改
buffer[I]的所有实例
*p
,以及(d)做我在
p
endp
strtol
中提到的事情。如果您有剩余的
缓冲区[i+1]
,您可以将其更改为
*(p+1)
p[1]
(类似于
+2
等)。如果您仍然需要在
k
上运行第二个循环,您可以使用
char*p2
执行类似的操作。