C中的一行客户端-服务器计算器



我正试图在linux中用C创建一个单行客户端-服务器计算器,但遇到了一些问题。我已经在客户端和服务器之间成功地创建了通信,我知道如何在它们之间传输数据。我的问题在于字符串操作过程。因此,我们的想法是运行./server PORTNUMBER./client IP PORTNUMBER。用于计算结果的代码位于服务器端,其他代码位于客户端端。在执行了这两项之后,用户被要求键入一个简单的计算,如10+54*9等。然后服务器计算结果,并将其发送回客户端进行显示。我选择使用字符串操作来处理这个问题(这是我最初的思考过程(。假设用户键入10*51。我将其保存到一个名为operation的字符串中。然后我执行if (strchr(operation,'*')) != NULL以进入适当的if语句。我创建了一个变量len1来计算所有字符,直到我遇到*和len1 = strlen(strchr(operation,'*'))。然后,我将其strncpy转换为一个新字符串(n=len1-1(,然后使用atoi函数获取第一个操作数。起初,对于第一个操作数(我指的是*之前的数字(,这似乎运行良好。然后我决定用strrev10*51变成15*01,重复整个过程,然后在保存为int之前再次用strrev把15变成51。所以我的想法是这样的:

len1 = strlen(strchr(oper, '*'));
strncpy(operand1string,operation,len1-1);
op1 = atoi(operand1string);
strrev(oper);
len2 = strlen(strchr(oper,'*'));
strncpy(operand2string,operation,len2-1);
strrev(operand2string);
op1 = atoi(operand2string);

但由于某种原因,这并没有像预期的那样奏效。我在这里走的是正确的道路,还是应该用另一种方式来实现它?任何建议都非常受欢迎。

语句len1 = strlen(strchr(operation,'*'))将为您提供从*到字符串末尾的字符数。它不会为您提供从字符串开头到*的字符数。如果需要从字符串开头到*的字符数,可以使用strchr(operation,'*') - operation

此外,我不建议使用函数strrev,因为将字符串反转两次似乎不必要地麻烦。

此外,正如其他人在评论部分已经指出的那样,函数strncpy在您的情况下不会写入终止null字符。

与其依赖这些功能,我相信以下方法会更好:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
enum operation_type
{
OPTYPE_ADDITION,
OPTYPE_SUBTRACTION,
OPTYPE_MULTIPLICATION,
OPTYPE_DIVISION
};
struct operation
{
enum operation_type type;
long left; //left operand
long right; //right operand
};
// On success, the function will return 0.
// On failure, it will return nonzero.
int parse_string( const char *input, struct operation *output )
{
long left, right;
enum operation_type type;
const char *p = input;
char *end;
//attempt to convert the left operand
left = strtol( p, &end, 10 );
if ( p == end )
return -1;
p = end;
//skip all whitespace
while ( isspace( (unsigned char)*p ) )
p++;
//interpret operator
switch ( *p )
{
case '+':
type = OPTYPE_ADDITION;
break;
case '-':
type = OPTYPE_SUBTRACTION;
break;
case '*':
type = OPTYPE_MULTIPLICATION;
break;
case '/':
type = OPTYPE_DIVISION;
break;
default:
return -1;
}
//move pointer one past the operator
p++;
//attempt to convert the right operand
errno = 0;
right = strtol( p, &end, 10 );
if ( p == end || errno == ERANGE )
return -1;
p = end;
//make sure that the remainder of the string is either
//empty or contains nothing except whitespace
while ( isspace( (unsigned char)*p ) )
p++;
if ( *p != '' )
return -1;
//function was successful, so fill the output struct
output->type = type;
output->left = left;
output->right = right;
return 0;
}

你可以这样调用函数:

int main( void )
{
struct operation op;
if ( parse_string( "20+30", &op ) == 0 )
{
printf( "left operand: %ldn", op.left );
printf( "right operand: %ldn", op.right );
switch ( op.type )
{
case OPTYPE_ADDITION:
printf( "operation type: additionn" );
printf( "result: %ldn", op.left + op.right );
break;
case OPTYPE_SUBTRACTION:
printf( "operation type: subtractionn" );
printf( "result: %ldn", op.left - op.right );
break;
case OPTYPE_MULTIPLICATION:
printf( "operation type: multiplicationn" );
printf( "result: %ldn", op.left * op.right );
break;
case OPTYPE_DIVISION:
printf( "operation type: divisionn" );
printf( "result: %ldn", op.left / op.right );
break;
default:
printf( "operation type: unknownn" );
}
}
else
{
printf( "parse failure!n" );
}
return 0;
}

在这种情况下,它将打印以下输出:

left operand: 20
right operand: 30
operation type: addition
result: 50

可以看出,字符串已经被正确地解析,因此可以根据写入struct operation的信息来简单地计算运算结果。

最新更新