如何使用系统调用write()和open()将字符串数组写入file.txt

时间:2017-12-07 15:15:01

标签: c arrays

我想将一个预定义的字符串数组写入file.txt,如下所示:

#include <unistd.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    char *somestr[] = {"haha\n", "aww\n", "hmm\n", "hello\n", "there\n"};
    int filedesc = open("testfile.txt", O_WRONLY | O_APPEND | O_CREAT);
    for (int i = 0; i < 5; ++i) {
        write(filedesc, somestr[i], 24);
    }
    return 0;
}

这将创建testfile.txt。预期的文件内容:

haha
aww
hmm
hello
there

但是当我尝试时,它给出了一个奇怪的结果。实际内容:

  

哈哈   \ 00aww   \ 00hmm   \ 00hello   \ 00there   \ 00aww   \ 00hmm   \ 00hello   \ 00there   \ 00testfihmm   \ 00hello   \ 00there   \ 00testfile.txhello   \ 00there   \ 00testfile.txt \ 00 \ 00there   \ 00testfile.txt \ 00 \ 00; 4 \ 00 \ 00 \ 00

2 个答案:

答案 0 :(得分:5)

您假设所有字符串的长度均为24个字符。这是不正确的。您正在边界外阅读并将其写入文件。

而是使用正确的长度。

write(filedesc, somestr[i], strlen(somestr[i]));

当然添加相应的包含文件 - 可以在strlen

的手册页上找到

答案 1 :(得分:2)

只是为了使代码更清晰,更易读以下是我的观察结果:

首次使用带有open()标志的O_CREAT系统调用时,您应该提供明确的permission,原因是如果您观察到open()写的人工页面作者:Michael Kerrisk, open()2参数 open()3参数

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode); 

当您使用creating系统调用open()文件和编写/附加/截断文件时,您应使用open() call with 3 argument。正如手册页所说

  • mode指定在创建新文件时使用的权限。指定O_CREAT时必须提供此参数           在flags中,并确保umask值未设置为0.

请参阅手册页“effective permissions由进程的umask修改               通常的方式“;

如果您尝试使用existing打开已open()个文件,则可以使用open() system call with 2 arguments作为手册页说“如果未指定O_CREAT,则模式被忽略“

所以替换这个

 int filedesc = open("testfile.txt", O_WRONLY | O_APPEND | O_CREAT);

 int filedesc = open("testfile.txt", O_WRONLY | O_APPEND | O_CREAT , 0664);
 if (filedesc == -1) {
     perror("open");
     …exit or return or …
 }

第二件事,somestr是一个char指针数组,每个指针可以有任意长度。如果您想使其成为通用字符,请使用strlen(somestr[i]),而不是随机的字符数(如上所述)。

int no_of_string = sizeof(somestr)/sizeof(somestr[0]);
for (int i = 0; i < no_of_string; ++i) {
    write(filedesc, somestr[i], strlen(somestr[i]));
}