【问题标题】:why \n in printf prints no value or old value of char array?为什么 printf 中的 \n 不打印字符数组的值或旧值?
【发布时间】:2019-03-08 01:54:53
【问题描述】:

当我遇到此错误时,我正在尝试测试命名管道。 我有一个名为 client.c 的文件,它写入命名管道。 我有一个名为 server.c 的文件,它从命名管道中读取并打印它的值。 看起来 server.c 有问题

客户端代码。

//-------CLIENT-----------
#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#define FIFO_FILE "MYFIFO"
int main()
{
    int fd, ch;
    char readbu[80];
    int write_byte;
    fd=open(FIFO_FILE,O_WRONLY);
    while(1)
    {
        printf("Enter choice \n1.Pepsi\n2.Coke\n3.Limca\n4.Maza\n");
        scanf("%d",&ch);
        switch(ch)
        {
            case 1: strcpy(readbu,"Pepsi\0");  
            write_byte=write(fd,readbu,sizeof(readbu));
            break;
            case 2: strcpy(readbu,"Coke\0");  
            write_byte=write(fd,readbu,sizeof(readbu));
            break;
            case 3: strcpy(readbu,"Limca\0");  
            write_byte=write(fd,readbu,sizeof(readbu));
            break;
            case 4: strcpy(readbu,"Maza\0");  
            write_byte=write(fd,readbu,sizeof(readbu));
            break;
            default:printf("Invalid");
            break;
        }
    }
    return 0;
}

服务器代码:

// Server code    
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#define FIFO_FILE "MYFIFO"
int main()
{
    int fd;
    char readbuf[80];
    char end[10];
    int to_end;
    int read_bytes;
    mknod(FIFO_FILE,S_IFIFO|0640,0);
    strcpy(end,"end");
    while(1)
    {
        fd=open(FIFO_FILE,O_RDONLY);
        read_bytes=read(fd,readbuf,sizeof(readbuf));
        readbuf[read_bytes]='\0';
        printf("Rec str = %s of len %d", readbuf,(int)strlen(readbuf));
        to_end=strcmp(readbuf,end);
        if(to_end==0)
        { close(fd);
            break;
        }`enter code here`
    }
    return 0;
}

在服务器端,上面的代码不打印任何输出。

如果我将 printf 语句更改为下面,那么我观察到第一次迭代它会打印空行,然后对于其他迭代它会打印旧值。

printf("\nRec str = %s of len %d", readbuf,(int)strlen(readbuf));

如果我将 printf 语句更改为以下,那么我观察到它打印了正确的值。

printf("Rec str = %s of len %d\n", readbuf,(int)strlen(readbuf));

我完全不明白 \n 是如何产生如此大的差异的。

我尝试使用 gdb 检查 readbuf 中的值,它实际上包含正确的值。 请帮助我理解这里的诀窍。

【问题讨论】:

  • 如果你在 Linux 上运行,在strace 下运行你的服务器进程,你会看到发生了什么,特别是如果你使用strace 发出你的服务器进程实际读取的数据管道。
  • strcpy(readbu,"Pepsi\0"); \0 到底在做什么?
  • stdout 行缓冲。在打印\n 之前,缓冲区的内容不会显示在屏幕上。因此将\n 放在printf 的末尾可以正常工作。
  • 另外,您不必在每次循环迭代中都使用fd=open(FIFO_FILE,O_RDONLY);
  • @AndrewHenle 当我签入 gdb 时,我观察到 readbuf 实际上有正确的数据。我了解标准输出是行缓冲的。但是,如果我们不在那里放任何 \n ,任何 printf 都可以工作。为什么当 readbuf 实际上有正确的数据时它会打印旧值?从哪里得到旧数据?

标签: c char printf


【解决方案1】:

输出缓冲区通常不会刷新,除非它已满、插入换行符或显式调用 fflush( stdout )

当你在输出的开头有换行符时,它会刷新之前缓冲的数据,并缓冲后面的数据。

以下将解决该问题:

printf("\nRec str = %s of len %d", readbuf,(int)strlen(readbuf));
fflush( stdout ) ;

【讨论】:

  • 感谢@Clifford 的回答。这对我帮助很大。我验证并成功了。
猜你喜欢
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多