为什么 write 系统调用打印的字符数不正确?

问题描述 投票:0回答:2

我正在尝试使用不同的 C 函数来实现

echo
命令。通过
printf
实现它相当简单:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    while (--argc)
        printf(((argc == 1) ? "%s\n" : "%s "), *++argv);
}

这效果很好:

$ ./a.out Bring a towel
Bring a towel

但是,当我尝试使用

write
系统调用来实现它时:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    while (--argc) {
        write(STDOUT_FILENO, *++argv, strlen(*argv));
        write(STDOUT_FILENO, ((argc == 1) ? "\n" : " "), 1);
    }
}

它正在打印长度不正确的字符串:

$ ./a.out Bring a towel
Bringa atow t

我用

strlen(*argv)
检查了
printf
返回的字符串长度,它们看起来是正确的。我也尝试在每次
write
后使用
fflush(stdout)
冲洗。为什么我的
write
系统调用无法正常工作?

c system-calls
2个回答
0
投票

您的代码调用未定义的行为,因为未指定参数的评估顺序。那里还有 bo 序列点。

如果你重写你的程序:

int main(int argc, char *argv[]) {
    while (--argc) {
        argv++;
        write(STDOUT_FILENO, *argv, strlen(*argv));
        write(STDOUT_FILENO, ((argc == 1) ? "\n" : " "), 1);
    }
}

它会工作得很好


0
投票

我添加了变量

iii
,用于
argv
的一些精确索引。增加
argv
根本没有达到您预期的结果。

我不确定你是否想要将换行符(

\n
)放置在原来的位置,因为它单独在一行上孤立了单词“towel”,但我保留了它,因为它毕竟准确地放置了换行符每个设计(当
argc
== 1 时)。

可运行的代码位于here,您可以根据需要查看和试验。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) 
{
    int iii=0;
    while (argc--) 
    {
        write(STDOUT_FILENO, argv[iii], strlen(argv[iii]));
        write(STDOUT_FILENO, ((argc == 1) ? "\n" : " "), 1);
        iii++;
    }

    return 0;
}

输出:


    ./output.s Bring a
    towel

© www.soinside.com 2019 - 2024. All rights reserved.