阅读'\ n'后fgets不可预知的行为

时间:2015-10-24 03:38:39

标签: c sockets newline system-calls fgets

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

  

如果读取换行符,则将其存储到缓冲区中。终止空值   byte('\ 0')存储在缓冲区中的最后一个字符之后。

 while (fgets(sendline, MAXLINE, stdin) != NULL) {
  sendline[strlen(sendline)-1] = '\0';
  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)没有变化 enter image description here

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

' 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]='\0'; // Remove newline from Buf
      send(sockfd, Buf, strlen(Buf), 0);
   }
}

答案 2 :(得分:0)

好的,问题出现在服务器接收块中。 我应该在puts()之后使用memset(); 或者甚至不使用puts(),将读取不同sys.call之间的差异。

在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] = '\0';

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

现在字符串不会覆盖它们。