0

I want to write a predefined array of strings to a file.txt, like so:

#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;
}

This will create testfile.txt. Expected file content:

haha
aww
hmm
hello
there

But when I tried, it gives a weird result. Actual content:

haha \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

1
  • Note that if the open() options include O_CREAT, the function requires a third argument which are the permissions on the file to be created. An octal value like 0644 is appropriate. Historically, 0666 was used, leaving it to umask and umask() to ensure that public write permission (and group write permission) are not given. Modern secure thinking avoids making things publicly writable even if umask is set to 0. Commented Dec 7, 2017 at 15:36

2 Answers 2

5

You are assuming that all the strings are 24 characters in length. This is incorrect. You are reading outside the bounds and writing this to file.

Instead use the correct length.

i.e.

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

Of course add the appropriate include file - this can be found on the manual page for strlen

Sign up to request clarification or add additional context in comments.

2 Comments

Great, Ed. Now she doesn't even have to look-up strlen in the manual!
Whoa that was fast :D now i can sleep in peace. I will accept this answer after minutes, due to limitation.
2

Just to make more clear and readable your code Here are my observation :

First thing when you are using open() system call with O_CREAT flag, you should provide explicit permission, reason for this is if you observe man page of open() written by Michael Kerrisk, open() with 2 argument and open() with 3 arguments.

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

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

when you are creating file and writing/appending/truncating file using open() system call you should use open() call with 3 argument . as man page says

  • mode specifies the permissions to use in case a new file is created. This argument must be supplied when O_CREAT is specified in flags and make sure umask value is not set to 0.

Refer the man pages for this "The effective permissions are modified by the process's umask in the usual way";

and if you try to open a already existing file using open() you can use open() system call with 2 arguments as man page says "if O_CREAT is not specified, then mode is ignored"

So replace this

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

with

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

Second thing, somestr is array of char pointers, each pointer can have any length. Instead of random no of characters (24 as mentioned), if you want to make it generic, use 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]));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.