C 编译中的write()警告消息

C 编译中的write()警告消息,c,warnings,C,Warnings,我有一段代码来创建一个函数来打印来自输入参数的消息 我一直在用c9.io编译代码,在没有警告的情况下运行得很好,但当我在本地执行时,它会显示如下警告: child2book:c39:11:警告:忽略“write”的返回值,用属性warn_unused_result[-Wunused-result]声明 这就是代码。当然write()定义有问题,但我对unix编程非常熟悉,不知道如何解决它。它执行得很好,但我想在我给老师讲课之前删除警告 这是代码: #include <stdlib.h>

我有一段代码来创建一个函数来打印来自输入参数的消息

我一直在用c9.io编译代码,在没有警告的情况下运行得很好,但当我在本地执行时,它会显示如下警告:

child2book:c39:11:警告:忽略“write”的返回值,用属性warn_unused_result[-Wunused-result]声明

这就是代码。当然write()定义有问题,但我对unix编程非常熟悉,不知道如何解决它。它执行得很好,但我想在我给老师讲课之前删除警告

这是代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>

#include "rutines.h"

void children();
void show_help();

int main(int argc, char *argv[])
{
    int ord;

    if (argc > 1)
        ord = atoi(argv[1]);
    if (argc == 1)
    {
        show_help("Error"); 
        exit(1);
    }

    children(ord);
}

void children(int ord)
{
    char msg[10];

    srand(getpid());
    sleep(rand() % 5);
    sprintf(msg, " %d", ord);
    while (strlen(msg) > 0)
    {
    int written= write(1, msg, strlen(msg));
    if (written < 0)
    break;

    exit(0);
}

void show_help(char *err_message)
{
    write_string(err_message,"");
    write_string("Usage: child2aok \n","");
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“rutines.h”
使儿童无效();
void show_help();
int main(int argc,char*argv[])
{
int ord;
如果(argc>1)
ord=atoi(argv[1]);
如果(argc==1)
{
显示帮助(“错误”);
出口(1);
}
儿童(ord);
}
无效子项(int ord)
{
char-msg[10];
srand(getpid());
睡眠(rand()%5);
sprintf(msg,“%d”,ord);
而(strlen(msg)>0)
{
int write=write(1,msg,strlen(msg));
如果(写入<0)
打破
出口(0);
}
无效显示帮助(字符*错误消息)
{
写入字符串(错误消息“”);
写入字符串(“用法:child2aok\n”,”);
}

您应该检查并处理
write()
命令返回的值。从
write
文档:

write[…]即使在有效条件下也可能返回小于count的值


为什么不直接使用
printf(“%d”,ord);
而不是
sprintf(msg,“%d”,ord);write(1,msg,strlen(msg))

write
并不保证写入所有数据;它可能只写入一个字节(或块,或返回一个错误…)。因此,您必须在循环中使用它:


如果写入了所有字节,则此函数返回
true
,如果出现错误,则返回
false

附加注释:此代码由另一个带有execlp函数的程序调用。printf不是write的替代品,与非常小的系统调用相比,它是一个相当大的函数,通常可以使用(void)(以及您不关心返回值的其他int类型函数)…也就是说,一个健壮的应用程序将使用返回值来验证是否写入了完整的数据;但是我还没有看到write()只要文件描述符有效,就会失败。此外,printf也有相同的返回类型问题。@technosaurus:我认为没有理由使用
sprintf/write
而不是
printf
。也就是说,如果你阅读
write
的文档,你会发现即使命令没有失败,它也可以返回非零。write也是如此e您必须检查返回代码,printf不必检查。write和printf都返回写入的字节数,零返回不是“成功”(参见kerrek的回答)。snprintf也不必要,您可以只使用itoa()用于写入的字符串。@technosaurus:kerrek的说法与我的意思相同。在不检查返回值的情况下不应使用write。相反,可以在不检查返回值的情况下使用printf。如果不检查返回值,则应相信标记该函数的库开发人员发出警告。无论如何,作为一项原则,如果你不能100%确定你在做什么,那么掩盖警告总是一个坏主意。kerrek的解决方案是可以的,但更简单、更清晰的方法是用printf替换sprintf/write。
bool write_all(int fd, void * buf, size_t len)
{
    size_t remaining = len;

    for (size_t n; (n = write(fd, buf, remaining)) > 0; remaining -= n)
    { }

    return remaining == 0;
}