fgets 读取 '\n' 后的意外行为

fgets unpredicted behavior after reading '\n'

尝试基于套接字在 C 中编写 echo server\client。 我无法理解 fgets() 是如何工作的。

If a newline is read, it is stored into the buffer. A terminating null byte ('[=12=]') is stored after the last character in the buffer.

 while (fgets(sendline, MAXLINE, stdin) != NULL) {
  sendline[strlen(sendline)-1] = '[=10=]';
  send(sockfd, sendline, strlen(sendline), 0);}

但是我在服务器上得到的是:

String received from and resent to the client:1234567890

String received from and resent to the client:abc
567890

如您所见,'\n' 字符添加到第二行,并尝试先覆盖,换行。但是在客户端,我看到缓冲区在使用 send() 时没有'\n'。

按 ctld+D (EOF) 按预期工作。

如何预防?并使用 Enter 键发送?

这张照片解释了我的意思。注释某些代码行后没有变化(@PCLuddite)

'0'和'\0'是有区别的。 '0' 表示它将其作为整数 0。因此,您必须给出 '\0' 或必须给出不带单引号的 0。在 char 中,0(没有单引号)是 NULL。

所以,如果你想删除输入中的新行,你可以使用下面的例子。

示例:-

char Buf[BUFSIZ];
while(fgets(Buf,BUFSIZ,stdin)!=NULL) {
   if(Buf[strlen(Buf)-1]=='\n') { //Prevent from EOF
      Buf[strlen(Buf)-1]='[=10=]'; // Remove newline from Buf
      send(sockfd, Buf, strlen(Buf), 0);
   }
}

当然接收端不是组成一个字符串,只是一个char的数组,没有空字符。发送 +1 以包含空字符。

while (fgets(sendline, sizeof sendline, stdin) != NULL) {
  size_t length = strlen(sendline);
  if (length > 0 && sendline[length-1] == '\n') {
     sendline[--length] = '[=10=]';
  }
  send(sockfd, sendline, length + 1, 0);  // + 1
}

好的,问题出在服务器接收块中。 我应该在 puts() 之后立即使用 memset(); 甚至不使用 puts(),也会读取不同 sys.calls.

之间的差异

在server.c中:

while ( (n = recv(connfd, buf, MAXLINE,0)) > 0)  {
   printf("%s","String received from and resent to the client:");
   puts(buf);
   memset(&buf, 0, strlen(buf));
}

或者只交换 client.c 中的 sizeof 和 strlen():

while (fgets(sendline, MAXLINE, stdin) != NULL) {
  if (sendline[(strlen(sendline)-1)] == '\n') {

      sendline[strlen(sendline)-1] = '[=11=]';

      //send(sockfd, sendline, strlen(sendline)+1, 0);
      send(sockfd, sendline, sizeof sendline, 0);
  }

现在字符串不会覆盖自己。