【问题标题】:If statement not loopingif语句不循环
【发布时间】:2015-10-07 21:52:40
【问题描述】:

我昨天有这个工作,但由于某种原因它已经停止了,我想做的是当用户键入命令“ADD”后跟名字、姓氏和电话号码时,它会将其附加到文件中.起作用的是在命令执行后,它会让我再次键入“ADD”fname、lname、phone,并增加计数器将其全部写入文件,它会让我这样做,直到我手动终止程序,并且每个条目将在文本文件中。现在它将多次接受该命令,但是它只会将我输入的第一个条目写入文件。

有人能发现我遗漏了什么吗?

"server.c" [dos] 200L, 5323Cc
/*
 * server.c
 */

#include <stdio.h>
#include <iostream>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>

using namespace std;

#define SERVER_PORT 1617
#define MAX_PENDING 5
#define MAX_LINE 512

int
main (int argc, char **argv)
{

struct sockaddr_in sin;
socklen_t addrlen;


char buf[MAX_LINE];
int len;
int s;
int new_s;
int r = 1000;
int result;
char message;
FILE *file_ptr;
string cmd, fn, ln, ph;
string add = "ADD";
string del = "DELETE";
string list = "LIST";
string quite = "QUIT";
string shutdown = "SHUTDOWN";



/* build address data structure */
bzero ((char *) &sin, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons (SERVER_PORT);

/* setup passive open */
if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
 {
  perror ("socket");
  exit (1);
}

if ((bind (s, (struct sockaddr *) &sin, sizeof (sin))) < 0)
{
  perror ("bind");
  exit (1);
}

listen (s, MAX_PENDING);

addrlen = sizeof (sin);
cout << "The server is up, waiting for connection" << endl;


  /* wait for connection, then receive and print text */
while (1)
{
  if ((new_s = accept (s, (struct sockaddr *) &sin, &addrlen)) < 0)
    { 
      perror ("accept");
      exit (1);
    }
  cout << "new connection from " << inet_ntoa (sin.sin_addr) << endl;

  while (len = recv (new_s, buf, sizeof (buf), 0))
    {
      /*send (new_s, buf, strlen(buf) + 1, 0);  original send to echo in client */

    /* create string stream from contents of buffer */
      stringstream stream (buf);

    /* read user input from string stream into strings for user input */
      stream >> cmd;
      stream >> fn;
      stream >> ln;
      stream >> ph;



  /* create character arrays and copy strings into character arrays */
      char command[9] = "        ";
      char fname[9] = "        ";
      char lname[9] = "        ";
      char phone[13] = "            ";

      cmd.copy (command, 8);
      fn.copy (fname, 8);
      ln.copy (lname, 8);
      ph.copy (phone, 12);




 /* determine if valid command received */
      /* Adds whatever follows the word "ADD" to the text file" */
      if (cmd.compare (add) == 0){
     {
          file_ptr = fopen ("file1.txt", "a+");
          fprintf (file_ptr, "%d" "%s" "%s" "%s" "%s", r, " ", fname,
                   lname, phone);
          fprintf (file_ptr, "\n");
          fclose(file_ptr);
          ++r;
        }
    }
/* LIST user input */
      else if (cmd.compare (list) == 0)
        {
          file_ptr = fopen ("file1.txt", "r");

          size_t count;
          while ((count = fread (buf, 1, sizeof buf, file_ptr)) > 0)
            {
              send (new_s, buf, count, 0);
              fclose (file_ptr);
            }
        }

      else if (cmd.compare (del) == 0)      /*Delete user input */
        {
          {
            FILE *fp1, *fp2;
            /*consider 40 character string to store filename */
            char filename[40];
            char c;
            int del_line, temp = 1;
            fp1 = fopen ("file1.txt", "r");
            c = getc (fp1);
            while (c != EOF)
              {
                printf ("%c", c);
                /*print current character and read next character */
                c = getc (fp1);
              }
            rewind (fp1);
            printf (" \n Enter line number of the line to be deleted:");
            /*accept number from user. */
            scanf ("%d", &del_line);


            fp2 = fopen ("copy.c", "w");
            c = getc (fp1);
            while (c != EOF)
              {
                c = getc (fp1);
                if (c == '\n')
                  temp++;


                if (temp != del_line)
                  {
                    /*copy all lines in file copy.c */
                    putc (c, fp2);
                  }
              }

            fclose (fp1);
            fclose (fp2);
            /*remove original file */
            remove ("file1.txt");
            /*rename the file copy.c to original name */
            rename ("copy.c", "file1.txt");
            printf
              ("\n The contents of file after being modified are as  follows:\n");
            fp1 = fopen ("file1.txt", "r");
            c = getc (fp1);
            while (c != EOF)
              {
                printf ("%c", c);
                c = getc (fp1);
              }
            fclose (fp1);

          }
        }
      else
        {
          cout << "Invalid Command" << endl;
        }

    }
  close (new_s);
}
}

【问题讨论】:

  • if 语句不应循环。
  • if 语句在哪种编程语言中用于循环?
  • 也许有一个外循环,但if (cmd.compare (add) == 0) 是做什么的? add 与数据有什么关系?
  • 也许我错过了它的标题,它应该允许我输入一个命令并多次执行它。添加了其余代码以进行说明
  • 需要 cmdfnlnph 的声明。 copy 方法有什么作用?

标签: c++ file file-io


【解决方案1】:

如果不大规模重写 OP 的代码,我无法提供有效的解决方案,因为这个程序太糟糕了。相反,这里有一些注意事项:

while (len = recv (new_s, buf, sizeof (buf), 0))

将recv返回码分配给len,然后测试len。如果 len 为 0,则退出循环。如果 len 是任何其他值,包括错误时 recv 的返回值 -1,则循环继续。

套接字错误的处理在功能上与此程序相同:

#include <iostream>

int main()
{
    int test;
    while (test = -1)
    {
        std::cout << "loop de ";
    }
}

这样不好。

TCP/IP 不能传送漂亮、干净的数据包,因为它是一个流协议。这在其他地方被打死了,所以我不会覆盖它或寻找链接。谷歌在这方面做得很好。

因为 TCP/IP 是一个流,recv 会为您提供它所拥有的任何数据,最大为给定缓冲区的大小。如果它什么都没有,它会等待某物的到来。

这意味着您可能会在一个 recv 或仅几个字节中收到多条消息。由于消息可能会在中间被截断,因此在 buf 中甚至可能没有终止的 null 会变成这样:

stringstream stream (buf);

放入一个神秘的手提袋中。您将不知道流中的内容。由于 OP 没有检查和处理来自 recv 的返回,因此他们可能会一遍又一遍地重新处理 buf 的最后内容,因为 recv 返回了错误代码并且没有数据。

流 >> cmd;

它的同伴流读取可能会也可能不会成功,因为它们没有经过测试,OP 永远不会知道。一旦一个失败,其余的读取都会失败,因为流的错误状态没有被清除。

这些:

cmd.copy (command, 8);

不会正确终止null。它们在 char 数组中写入的距离不够远,无法覆盖以初始化方式放置在最后一个元素中的 null,因此后续的 fprintfs 将继续存在,但不会打印正确的结果。

因此,鉴于上述雷区,输出不正确并不奇怪,也不值得尝试提供解决方案。

在继续这个程序之前,OP 需要阅读并练习套接字编程和标准流。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-02
    相关资源
    最近更新 更多