我正在尝试使用不同的 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
系统调用无法正常工作?
您的代码调用未定义的行为,因为未指定参数的评估顺序。那里还有 bo 序列点。
如果你重写你的程序:
int main(int argc, char *argv[]) {
while (--argc) {
argv++;
write(STDOUT_FILENO, *argv, strlen(*argv));
write(STDOUT_FILENO, ((argc == 1) ? "\n" : " "), 1);
}
}
它会工作得很好
我添加了变量
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