-1

I am new to C and I'm trying to get familiar with low level I/O such as read() and write(), and I'm trying to print lines to standard out from a file using it, but I can't figure out how to do it while still only using low level functions.

Heres what I have so far, any suggestions would be super appreciated

enter image description here

I tried to iterate through the char array I have and checking for '\n' but it doesn't seem to be doing the trick for me.

EDIT: Sorry, here's the code to be copied

    int lineCounter = 0;
    char* filename = argv[3];
    int fd = open(filename, O_RDONLY);
    
    //off_t size = lseek(fd, 0, SEEK_END);
    
    if (fd == -1) perror("open");

    int n;
    char buffer[BUFFSIZE];

    while ((n = read(fd, buffer, 1)) > 0) {
        write(STDOUT_FILENO, buffer, 1);
    }
    
    for (int i = 0; i < BUFFSIZE; i++) {
        
        if (buffer[i] == '\n') {
            lineCounter++;
        }
        
    }
maltreat
  • 1
  • 1
  • 4
    Please post code, errors, sample data or textual output here as plain-text, not as images that can be hard to read, can’t be copy-pasted to help test code or use in answers, and are barrier to those who depend on screen readers or translation tools. You can edit your question to add the code in the body of your question. For easy formatting use the `{}` button to mark blocks of code, or indent with four spaces for the same effect. The contents of a **screenshot can’t be searched, run as code, or easily copied and edited to create a solution.** – tadman Nov 09 '22 at 00:05
  • 1
    You should generally stick to using `FILE*` unless you need unbuffered access specifically, and those occasions are quite rare. The performance cost of doing tiny reads can be considerable, and reading/writing single bytes is absolutely brutal. Try and read in 1KB blocks, *minimum*. Remember, each `read()` requires a trip through the kernel, through to the drive, and back again, which can be considerable. Reading 1 byte and 1KB takes effectively the same amount of time on modern hardware, so your code is 1024x slower. – tadman Nov 09 '22 at 00:06
  • 2
    Hello! Welcome to Stack Overflow! [Please do not post a screenshot of your code](https://meta.stackoverflow.com/questions/285551/why-should-i-not-upload-images-of-code-data-errors/285557#285557), but copy and paste it on your question [as a code format](https://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks). – Jiho Kim Nov 09 '22 at 00:07
  • that code looks like it should work, what goes wrong? What did you see when you stepped through with a debugger. Also - do not post images of code, we cannot copy it into out IDE to test out – pm100 Nov 09 '22 at 00:22
  • 1
    your loop should be up to n not BUFFSIZE, the rest of the buffer contains junk – pm100 Nov 09 '22 at 00:23
  • 1
    You're only using the first character of `buffer`, since you're repeatedly reading and writing a single character (which you shouldn't be doing with unbuffered I/O - you're just hammering on your disk for no reason). After the `while` loop, you're trying to count lines, but that can't possibly work since you only saved the last character that you read. Either count the lines in your `while` loop, or else save the entire file without overwriting your data. In the latter case, you may need to use `malloc` and `realloc` to grow the buffer as needed. – Tom Karzes Nov 09 '22 at 00:40
  • The `while` loop reads the whole file one character at a time. The `for` loop happens after it is done, and the only actual value that came from the file is `buffer[0]`, the rest is uninitialized junk. The only thing you can tell outside the loop is if the last character was a newline or not. You need to be checking after each read into the buffer inside the `while` loop and you should probably read more than one character at a time. – Retired Ninja Nov 09 '22 at 00:43
  • Note that `if (fd == -1) perror("open");` is not safe. It reports the error, but then continues as if nothing had gone wrong. You either need to return an error indication from this function or you should exit after printing the error: `if (fd == -1) { perror(filename); exit(EXIT_FAILURE); }` — that also reports on the name of the file rather than the system call that failed, which is beneficial if you use a short-circuit error report like `perror()`. – Jonathan Leffler Nov 09 '22 at 01:40

1 Answers1

0

corrections

int lineCounter = 0;
char* filename = argv[3];
int fd = open(filename, O_RDONLY);

//off_t size = lseek(fd, 0, SEEK_END);

if (fd == -1) perror("open");

int n;
char buffer[BUFFSIZE];

while ((n = read(fd, buffer, BUFFSIZE)) > 0) { <<<=== read uoto BUFFSIZE
    write(STDOUT_FILENO, buffer, n); <<<<=== write out the same number of read bytes


    for (int i = 0; i < n; i++) { <<<<=== put line counter inside loop to read file && loop over read number of chars
    
       if (buffer[i] == '\n') {
         lineCounter++;
       }
    
     }
  }
pm100
  • 48,078
  • 23
  • 82
  • 145