简体   繁体   中英

Using read() system call

For an assignment in class we were tasked with using the read() function to read a file containing numbers. While I was able to read the numbers into a buffer I have been unable to move them from the buffer into a char *array so that they can be easily accessed and sorted. Any advice is appreciated.

int readNumbers(int hexI, int MAX_FILENAME_LEN, int **array, char* fname) {
    int numberRead = 0, cap = 2;
    *array = (int *)malloc(cap*sizeof(int));
    int n;
    int filedesc = open(fname, O_RDONLY, 0);
    if(filedesc < 0){
        printf("%s: %s\n", "COULD NOT OPEN", fname);
        return -1;
    }
    char * buff = malloc(512);
    buff[511] = '\0';
   while(n = read(filedesc, buff+totaln, 512 - totaln) > 0) //Appears to loop only once
            totaln += n;
    int len = strlen(buff);
    for (int a = 0; a < len; a++) {  //Dynamically allocates array according to input size
        if ((&buff[a] != " ") && (&buff[a] != '\n'))
            numberRead++;
        if (numberRead >= cap){
            cap = cap*2;
            *array = (int*)realloc(*array, cap*sizeof(int));
        }
    }
    int k = 0;
    while((int *)&buff[k]){  //attempts to assign contents of buff to array
        array[k] = (int *)&buff[k];
        k++;
    }
}

Your use of read() is wrong. There are at least two serious errors:

  1. You ignore the return value, except to test for end-of-file.
  2. You seem to assume that read() will append a nul byte after the data it reads. Perhaps even that it will pad out the buffer with nul bytes.

If you want to read more data into the same buffer after read() returns, without overwriting what you already read, then you must pass a pointer to the first available position in the buffer. If you want to know how many bytes were read in total, then you need to add the return values. The usual paradigm is something like this:

/*
 * Read as many bytes as possible, up to buf_size bytes, from file descriptor fd
 * into buffer buf.  Return the number of bytes read, or an error code on
 * failure.
 */
int read_full(int fd, char buf[], int buf_size) {
    int total_read = 0;
    int n_read;

    while ((n_read = read(fd, buf + total_read, buf_size - total_read)) > 0) {
        total_read += n_read;
    }

    return ((n_read < 0) ? n_read : total_read);        
}

Having done something along those lines and not received an error, you can be assured that read() has not modified any element of the buffer beyond buf[total_read - 1] . It certainly has not filled the rest of the buffer with zeroes.

Note that it is not always necessary or desirable to read until the buffer is full; the example function does that for demonstration purposes, since it appears to be what you wanted.

Having done that, be aware that you are trying to extract numbers as if they were recorded in binary form in the file. That may indeed be the case, but if you're reading a text file containing formatted numbers then you need to extract the numbers differently. If that's what you're after then add a string terminator after the last byte read and use sscanf() to extract the numbers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM