0

用户输入 2 个数字和 +、-、/、* 并且应该得到答案。问题是,它没有显示他们正确输入的内容,也没有计算。为什么是这样?我提供了一个屏幕截图来显示我得到了什么。我该如何解决?http://imageshack.us/photo/my-images/404/mathfn.jpg/

#include <iostream>
using namespace std;

#include <stdio.h>
#include <string.h>
#include <winsock.h>

// Function prototype
void StreamClient(char *szServer, short nPort);

// Helper macro for displaying errors
#define PRINTERROR(s)   \
        fprintf(stderr,"\n%s: %d\n", s, WSAGetLastError())

////////////////////////////////////////////////////////////

void main(int argc, char **argv)
{
    WORD wVersionRequested = MAKEWORD(1,1);
    WSADATA wsaData;
    int nRet;
    short nPort;

    //
    // Check for the host and port arguments
    //
    if (argc != 3)
    {
        fprintf(stderr,"\nSyntax: TCPTimeClient ServerName PortNumber\n");
        return;
    }

    nPort = atoi(argv[2]);

    //
    // Initialize WinSock and check the version
    //
    nRet = WSAStartup(wVersionRequested, &wsaData);
    if (wsaData.wVersion != wVersionRequested)
    {   
        fprintf(stderr,"\n Wrong version\n");
        return;
    }

    //
    // Go do all the stuff a datagram client does
    //
    StreamClient(argv[1], nPort);

    //
    // Release WinSock resources
    //
    WSACleanup();

    printf("\nPlease enter a floating point number: ");
float number1;
scanf("%f", &number1);

printf("\nPlease enter a mathematical operator (+,-,*,/): ");
char mathOperator;
scanf("%f", &mathOperator);


printf("\nPlease enter a floating point number: ");
float number2;
scanf("%f", &number2);

printf("\nCalculating %f %f %f...", &number1, &mathOperator, &number2);

printf("\nPlease enter a floating point number: ");
float number3;
scanf("%f", &number2);

}

////////////////////////////////////////////////////////////

void StreamClient(char *szServer, short nPort)
{
    int nRet;                       // return code
    char szBuf[256];                // client buffer area 
    char szSvr[256];                // server name

    LPHOSTENT lpHostEntry;          // host data structure
    SOCKET  theSocket;              // client socket
    SOCKADDR_IN saClient;           // socket address structure

    //
    // Get local machine name
    //
    nRet = gethostname(szSvr, sizeof(szSvr));

    //
    // Check for errors
    //
    if (nRet == SOCKET_ERROR)
    {
        PRINTERROR("gethostname()");
        return;
    }

    // 
    // Display an informational message
    //
    printf("Datagram Client [%s] sending to server [%s] on port %d...\n",
                                szSvr, szServer, nPort);

    //
    // Find the server
    //
    lpHostEntry = gethostbyname(szServer);
    if (lpHostEntry == NULL)
    {
        PRINTERROR("gethostbyname()");
        return;
    }

    //
    // Create a TCP/IP datagram socket
    //
    theSocket = socket(AF_INET,         // Address family
                       SOCK_STREAM,     // Socket type
                       0);              // Protocol

    //
    // Check for errors
    //
    if (theSocket == INVALID_SOCKET)
    {
        PRINTERROR("socket()");
        return;
    }

    //
    // Fill in the address structure of the server
    //
    saClient.sin_family = AF_INET;
    saClient.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
                                        // ^ Client's address
    saClient.sin_port = htons(nPort);   // Port number from command line

    //
    // Connect to the server
    //
    nRet = connect(theSocket, 
            (struct sockaddr *)&saClient, 
            sizeof(saClient));

    //
    // Check for errors
    //
    if(nRet == SOCKET_ERROR)
    {
      PRINTERROR("Connect()");
      return;
    }

    //
    // Prepare some data to send to the server
    //
    sprintf(szBuf, "From the Client [%s]", szSvr);

    //
    // Send data to the server
    //
    nRet = send(theSocket,                  // Socket
                  szBuf,                    // Data buffer
                  (int)strlen(szBuf),       // Length of data
                  0);                       // Flags

    //
    // Check for errors
    //
    if (nRet == SOCKET_ERROR)
    {
        PRINTERROR("send()");
        closesocket(theSocket);
        return;
    }

    //
    // Zero out the incoming data buffer
    //
    memset(szBuf, 0, sizeof(szBuf));

    //
    // Wait for the reply
    //
    nRet = recv(theSocket,                  // Socket
                szBuf,                      // Receive buffer
                sizeof(szBuf),              // Length of receive buffer
                0);                         // Flags

    //
    // Check for errors
    //
    if (nRet == SOCKET_ERROR)
    {
        PRINTERROR("recv()");
        closesocket(theSocket);
        return;
    }

    //
    // Display the data that was received
    //
    printf("\n%s", szBuf);

    //
    // Close the socket
    //
    closesocket(theSocket);
    return;


}
4

1 回答 1

1

我不明白为什么你不能输入字符,所以我创建了一个测试程序 - 果然是相同的行为!我不经常 scanf(),但我猜想 scanf("%c") 正在抓取缓冲区中的任何字符 - 如果有的话 - 并在我们有机会输入任何内容之前继续。所以我把它完全明确了——为 fscanf/fgetchar 流指定“stdin”并执行 fflush() 以确保在读取之前它是空的。此外,我完全停止使用 scanf() 只是为了获得一个字符。就是这样!这是完整的程序:

printf("Please enter a floating point number: ");
float number1;
fscanf(stdin,"%f", &number1);

printf("Please enter a mathematical operator (+,-,*,/): ");
char mathOperator;
//fscanf(stdin,"%f", &mathOperator);

fflush(stdin);
mathOperator = (char)fgetc(stdin);

printf("Please enter a floating point number: ");
float number2;
fscanf(stdin,"%f", &number2);

printf("\nCalculating %f %c %f...", number1, mathOperator, number2);

float result = 0.0F;
switch (mathOperator) {
case '+':
    result = number1 + number2;
    break;
case '-':
    result = number1 - number2;
    break;
case '/':
    result = number1 / number2;
    break;
case '*':
    result = number1 * number2;
    break;
default:
    printf("\nInvalid operator entered!");
}

printf( "\n\nThe answer is %0.1f\n", result );

fflush(stdin);
char ch = getc(stdin);  // wait for keypress

这是测试运行的输出:

Please enter a floating point number: 3.4
Please enter a mathematical operator (+,-,*,/): *
Please enter a floating point number: 2

Calculating 3.400000 * 2.000000...

The answer is 6.8

[结束更新]

您使用 printf() 遇到的具体问题是您正在传递浮点值的地址 - 而不是值本身。

printf("\nCalculating %f %f %f...", &number1, &mathOperator, &number2);

应该:

printf("\nCalculating %f %f %f...", number1, mathOperator, number2);

下一个问题是“mathOperator”——看起来您要求用户输入一个字符,但在 printf() 中指定的数据类型是浮点数。那是行不通的。

所以 printf真的应该更像:

printf("\nCalculating %f %c %f...", number1, mathOperator, number2);

假设“mathOperator”中有一个“+”、“-”等。

至于它为什么不计算 - 我没有看到(可能只是为了简洁而省略)任何代码来实际进行计算。

[计算更新]

由于唯一允许的运算符是 '+'、'-'、'/'、'*' 并且操作数始终是浮点数,因此计算逻辑非常简单:

float result = 0.0F;
switch (mathOperator) {
case '+':
    result = number1 + number2;
    break;
case '-':
    result = number1 - number2;
    break;
case '/':
    result = number1 / number2;
    break;
case '*':
    result = number1 * number2;
    break;
}

然后你可能想添加一个 printf() 来输出结果(和/或通过 TCP 发回):

printf( "The answer is" "%0.1f\n", result );

如果您进行更高级的计算,您必须担心运算符优先级、类型转换等。一个简单的“案例”是不够的。您需要查看解析器以从表达式构建解析树并根据某些规则(语法)对其进行评估。但相信我——你想先掌握这个;-)

请参阅此问题以了解所涉及的内容。

于 2013-03-17T23:51:59.640 回答