2

我目前正在使用以下命令写入程序的输出文件。我想获取存储在二维数组中的字符串并将其写入我设置的输出文件,即“url_storage.txt”。

下面的示例显示了我如何在程序开始附近设置文件(即初始文件描述符声明和对 open(...) 的调用)并显示对 write(...) 的主要调用,它发生在一个while循环(从二维数组中的每个槽写入,或字符串/字符数组的集合)。我的问题是我想在每个字符串之后插入一个 NEWLINE 字符,但是,以下代码不会产生一个文件,每个字符串(或每次写入的结果)都在单独的行上。有没有什么简单的方法可以让 write 函数识别我希望它遵守换行符?我还发现有一个函数 lseek(...) 可以调整我的文件位置指针(看起来它对于换行调整并不是很有用)。关于如何让它指向下一行的任何建议?

int fd2 = open("/directory/path/to/target/output/file/url_storage.txt", O_WRONLY, O_CREAT, 00777);

...
while(...){
      ...
      (void) write(fd2, (" %s \n", matches[ind]), strlen(matches[ind]));
}
4

1 回答 1

4

这:

write(fd2, (" %s \n", matches[ind]), strlen(matches[ind]));

不做你认为它做的事。你混淆printf()write(). “格式字符串”" %s \n"是逗号表达式的第一部分,实际上被丢弃了。仅将字符串写入文件。您必须单独编写换行符:

if (write(fd2, " ", 1) != 1 ||
    write(fd2, matches[ind], strlen(matches[ind])) != strlen(matches[ind]) ||
    write(fd2, " \n", 2) != 2)
    ...something went wrong...

dprintf()或者考虑使用类似于fprintf()但写入文件描述符而不是文件流的POSIX 。

if (dprintf(fd2, " %s \n", matches[ind]) != strlen(matches[ind])+3)
    ...something went wrong...

我试图遵循您的意图,在字符串之前和之后添加一个空格,但如果它是我的代码,至少会省略尾随空格(几乎在任何情况下都不需要换行符之前的空格 -除了--在电子邮件中标记签名开始的那个之后。前面的空格可能需要将字符串与之前的字符串分开。但是,我可能会写:

if (dprintf(fd2, "%s\n", matches[ind]) != strlen(matches[ind])+1)
    ...something went wrong...

write()或具有单独调用的等效项。


顺便说一句,你写了相当于:

 const char path[] = "/directory/path/to/target/output/file/url_storage.txt";
 int fd2 = open(path, O_WRONLY, O_CREAT, 00777);

由于复杂的历史原因,原型open()int open(const char *path, int flag, ...);,但只有 2 或 3 个参数是有效的,并且您使用了 4。您应该这样写:

 int fd2 = open(path, O_WRONLY|O_CREAT, 0777);

但是编译器不能轻易地诊断出错误;毕竟,原型说的是“任意数量的参数”。此外,除非您正在编写 shell 脚本,否则该文件不应该是可执行的(所以 0666 而不是 0777),我愿意争辩说它也不应该是公开可写的,所以 0664 甚至 0644 会更好,尽管umask值的可用性。顺便说一句,使用类似变量path而不是文字的一个优点是,如果您不必重复字符串文字,则使用文件名更容易报告有意义的错误消息。

于 2013-03-14T04:19:52.200 回答