我无法理解此聊天程序的结果

时间:2019-06-27 14:14:41

标签: c scanf fifo

因此,我制作了一个简单的服务器-客户端程序,可以使用fifo文件(msgfifo)相互通信。

我的问题是:当我键入包含空格的消息时,接收方进程运行几次,且单词数不计。

这不是我期望的,因为我希望将其打印成一个完整的句子,但事实并非如此,我想知道为什么。

当我键入要发送的内容时,将SIGUSR1信号发送给另一个。

/* receive msg part */
/* added this using sigset(SIGUSR1, receiveSIGUSR1) */

void receiveSIGUSR1()
{
    char* msg = "\nIncoming Message from client...";
    char* msg2 = "\nClient : ";
    char buf[max_of_msg];
    int fd;
    write(1, msg, strlen(msg)+1);
    fflush(stdin);
    if( (fd = open("./msgpipe", O_RDONLY)) < 0)
    {   perror("open"); exit(1);    }
    read(fd, buf, max_of_msg);
    close(fd);
    write(1, msg2, strlen(msg2)+1);
    write(1, buf, strlen(buf)+1);
    flag = 0;
}

/*send msg part*/

while(1)
{
    flag = -1;
    printf("\nType what u want to send : ");
    scanf(" %s", msg);
    if(flag == 0)   continue;
    printf("msgtaken\n");
    fflush(stdin);
    if( (fd = open("./msgpipe", O_RDWR)) < 0)
    {   perror("exit"); exit(1);    }
    kill(clpid, 30);
    sleep(2);
    printf("Send message to Client..\n");
    write(fd, msg, max_of_msg);
    printf("Message Sent...\n");
}

预期:

  

客户端:您好,服务器是客户端

实际: / *服务器* /

  


来自客户端的传入消息...
您好
传入消息   来自客户...

来自客户...
的传入消息是   
来自客户端的传入消息...
客户端

键入您要输入的内容   要发送:

/ 客户端 /

  


键入您要发送的内容:Hello Server这是客户端   
msgtaken
将消息发送到服务器。
消息已发送
  
键入您要发送的内容:msgtaken
将消息发送到服务器。   
消息已发送

键入您要发送的内容:msgtaken
发送   消息发送到服务器。
消息发送

键入您要发送的内容   :msgtaken
将消息发送到服务器。
消息已发送

类型   您要发送的内容:msgtaken
发送消息到服务器。   
消息已发送

     


输入您要发送的内容:

1 个答案:

答案 0 :(得分:1)

这是因为这是输入的方式:

scanf(" %s", msg);

让我们看看scanf(重点是我的)的文档:

  

s:任意数量的非空白字符,在第一个字符处停止   找到空格字符。终止的空字符是   自动添加到存储序列的末尾。

这就是为什么在发送Hello时它会在Hello Server this is client之后停止的原因。还要注意" %s"中的空格,这意味着它也会在输入开始时忽略任何空格。因此,当它在下一次遍历循环时读取Server时,将使其忽略HelloServer之间的空格。结果,它经历了五次循环,并且每次的消息分别为HelloServerthisisclient

相反,您可以使用getline

char *message = NULL;
size_t length;
getline(&message, &length, stdin);
// use message
free(message);

注意一点:为了使您的scanf通话更加安全,您可以为字符串输入指定最大大小:

scanf(" %99s", msg);

每个示例,这意味着只能读取99 char,再加上一个空终止符,缓冲区大小为100。这样,您可以避免如果用户输入以下内容会发生未定义的行为:对于缓冲区来说太大的字符串。