skip to Main Content

I receive some parameters that I transform into char and concatenate to create a string that is written into a .txt file. I tried adding a 0 at the end of said string as a line terminator. However, when I use file 10.txt on my ubuntu terminal, I get 10.txt: ASCII text, with no line terminators

What do I need to change in order to add a line terminator?

int main() {
    int res;
    res = set_value(10, "abc", 3, 2.0);
}

int set_value(int key, char *value1, int value2, double value3) {
    char name[1000];
    int status;
    char line[5000];
    char temp[1000];
    int n;

    // Change directory where we work.
    if (chdir("FilesPractice1") == -1) {
        perror("Error while changing directories.");
        return -1;
    }

    // Convert key to the name of the file.
    snprintf(name, 1000, "%d.txt", key);

    // Open the file.
    if ((status = open(name, O_RDONLY)) == -1) {
        // Since the file doesnt exist, we proceed to create it.
        if ((status = open(name, O_WRONLY | O_CREAT, 0666)) == -1) {
            perror("Error while creating the tuple.n");
            return -1;
        }
        // Format the key and values to write them into the file.
        snprintf(line, 5000, "%d, ", key);
        
        n = strlen(value1);
        strncat(line, value1, n);
        
        snprintf(temp, 1000, ", %d, ", value2);
        n = strlen(temp);
        strncat(line, temp, n);
        
        snprintf(temp, 1000, "%f", value3);
        n = strlen(temp);
        strncat(line, temp, n);
        
        n = strlen(line);
        line[n + 1] = 0;

        // Write the values into the file.
        write(status, line, strlen(line));

    } else {
        // Since file already exists, it is considered an error.
        perror("Error: key value already exists.n");
        return -1;
    }

    // Close the file.
    if (close(status) == -1) {
        perror("Error while closing the file.");
        return -1;
    }

    return 0;
}

2

Answers


  1. "ASCII text, with no line terminators" means there is no line ending at the end of the file (CR or LF).
    It is not an error, it just describes the content of the file.

    If you want to add line terminators as said, instead of:

    ...
    n = strlen(line);
    line[n + 1] = 0;
    ...
    

    Change those 2 lines into the line below for LF (Linux convention):

    strcat(line, "n");
    

    Or if you want both CR and LF (Windows convention):

    strcat(line, "rn");
    

    EDIT: Changed strncat into strcat.

    Login or Signup to reply.
  2. In order to append a newline to the string, just use strcat(line, "n");

    Also note these remarks:

    • calling strncat(line, temp, strlen(temp)) is exactly equivalent to strcat(line, temp).

    • you forget to close the file if it already exists.

    • the set_value function should be defined or at least declared before the main function.

    There is no reason to use separate calls to snprintf in your code, you could simply write:

        snprintf(line, sizeof line, "%d, %s, %d, %fn",
                 key, value1, value2, value3);
    

    If you must for some reason construct the output line one field at a time, you can simplify the code by keeping track of the position in the output line instead of using separate arrays for the fragments and concatenating them with strcat:

    #include <stdio.h>
    
    int set_value(int key, char *value1, int value2, double value3) {
        char filename[32];
        int status;
        char line[5000];
    
        // Change directory where we work.
        if (chdir("FilesPractice1") == -1) {
            perror("Error while changing directories.");
            return -1;
        }
    
        // Convert key to the name of the file.
        snprintf(filename, sizeof filename, "%d.txt", key);
    
        // Open the file.
        if ((status = open(filename, O_RDONLY)) != -1) {
            // The file already exists, close it and report the error
            close(status);
            // Cannot use `perror` as `errno` was not set
            fprintf(stderr, "Error: key value file %s already exists.n", filename);
            return -1;
        }
    
        // Since the file doesn't exist, we proceed to create it.
        if ((status = open(name, O_WRONLY | O_CREAT, 0666)) == -1) {
            perror("Error while creating the tuple.n");
            return -1;
        }
        // Format the key and values to write them into the file.
    #if 0
        // Single call to snprintf
        size_t pos = snprintf(line, sizeof line, "%d, %s, %d, %fn",
                              key, value1, value2, value3);
    #else
        // Separate calls for different parts
        size_t pos = snprintf(line + pos, sizeof line - pos, "%d", key);
        if (pos < sizeof line)
            pos += snprintf(line + pos, sizeof line - pos, ", %s", value1);
        if (pos < sizeof line)
            pos += snprintf(line + pos, sizeof line - pos, ", %d", value2);
        if (pos < sizeof line)
            pos += snprintf(line + pos, sizeof line - pos, ", %f", value3);
        if (pos < sizeof line)
            pos += snprintf(line + pos, sizeof line - pos, "n");
    #endif
        // Check if line is long enough.
        if (pos >= sizeof line) {
            fprintf(stderr, "Buffer size too small: need %zu bytesn", pos + 1);
        }
        // Write the values into the file.
        ssize_t len = strlen(line);
        ssize_t nwritten = write(status, line, len);
        if (nwritten != len) {
            fprintf(stderr, "Error writing to %s: %zd bytes written, expected %zd.n",
                    filename, nwritten, len);
        }
    
        // Close the file.
        if (close(status) == -1) {
            perror("Error while closing the file.");
            return -1;
        }
    
        return 0;
    }
    
    int main(void) {
        int res;
        res = set_value(10, "abc", 3, 2.0);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search