Writing a New Line to a File

16,718

This:

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

does not do what you think it does. You're confusing printf() with write(). The 'format string' " %s \n" is the first part of a comma expression and is effectively thrown away. The string alone is written to the file. You'll have to write the newline separately:

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

Or consider using POSIX dprintf() which is similar to fprintf() but writes to a file descriptor instead of a file stream.

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

I've tried to follow what seems to be your intent, adding a space before and after the string, but were it my code, the trailing space at least would be omitted (no need for a space before a newline in almost any circumstances — except after the -- that marks the start of a signature in email. The preceding space might be necessary to separate the string from what went before. However, I'd probably write:

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

Or the equivalent with separate write() calls.


Incidentally, you wrote the equivalent of:

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

For complicated historical reasons, the prototype of open() is int open(const char *path, int flag, ...);, but only 2 or 3 arguments are valid and you've used 4. You should have written:

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

but the compiler can't readily diagnose the mistake; after all, the prototype says 'any number of arguments'. Also, unless you're writing a shell script, the file should not be executable (so 0666 instead of 0777), and I'd be willing to argue that it should not be publicly writable either, so 0664 or even 0644 would be better, notwithstanding the availability of a umask value. Incidentally, one advantage of using a variable like path instead of a literal is that it is easier to report meaningful error messages using the file name if you don't have to repeat the string literal.

Share:
16,718
9codeMan9
Author by

9codeMan9

I am a graduate student in IST with a background in Computer Science and Engineering, Philosophy, and Mathematics. I am currently conducting research in deep architectures for efficient, large-scale learning. My interests include: Artificial Intelligence: Intelligent Agents, Neural Networks, and Knowledge Representation Complex Systems, Artificial Intuition & Artificial Creativity Computer Graphics and Computer Vision How human agents and software agents can work together to solve problems (HCI + AI) Lambda Calculus, Interpreters

Updated on June 04, 2022

Comments

  • 9codeMan9
    9codeMan9 almost 2 years

    I am currently using the following commands to write to an output file for my program. I want to take strings stored in a 2D array and write it to an output file I have set up, which is "url_storage.txt".

    The example below shows how I have set up the file near the start of the program (i.e. the initial file descriptor declaration and call to open(...)) and shows the primary call to write(...), which occurs in a while loop (writing from each slot in the 2D array, or collection of strings/character arrays). My issue is that I want to insert a NEWLINE character after each string, however, the following code does not yield a file with each string (or result of each write) on a separate line. Is there any simple way for the write function to recognize that I want it to adhere to the newline character? I also found that there is a function lseek(...) which will adjust my file position pointer (it looks like it's not really useful for new line adjustments). Any suggestions on how to get that to point to the next line?

    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]));
    }