Question

I have an exercise to do where I need to code in C, commands equivalent to cat and nl using only system calls. The system calls given to us are open(), close(), read() and write().

I've already done the "cat" equivalent and it seems to be running fine, now I need to do the "nl" one but I'm having trouble with how am I going to write line by line.

The idea is to use the less system calls possible.

I know I need to find the '\n' on the buffer and I could do a while to loop through the buffer and find the '\n' position (let's call it X) then write X number of bytes to stdout.

But looping through all chars in the buffer searching for the end of the line doesn't feel right to me, but I have no idea how else could I do this...

IMPORTANT EDIT:
I think some of you are missing the point on my question... I don't need explanations on how to do this, that's not my problem. I know how to do it (or have a very good idea, I just haven't tried it yet). The "problem" is that it doesn't feel right to loop through the buffer, file or whatever, char by char, to find the end of the line (no matter how). I'm not saying this is not the answer or that I'm not allowed to do this and that, I'm just talking about what I think. It just seems an odd way to do this, that's all... But if that's the way, than that's the answer to my question.

I apprecite everyone's help though :)

Was it helpful?

Solution

You will have to search the buffer for \n, there is no way around it. Don't worry about the performance, the progam will spend most of the time in read and write.

Also, make sure you make the buffer sufficiently large. Don't call read(file,&c,1) as it will be incredibly slow.

OTHER TIPS

The only way to find a '\n' is to search for it. If you can't use strchr(3), you've got to iterate over the buffer to find what you're looking for (read: implement it).

If you don't know the lengths of the lines in advance, there is no shortcut for finding the place of the \n. That is, unless you use a readily implemented function for splitting the lines, but that would probably just do the same thing somewhere down the line.

That is, yes, you have to loop through the chars :)

A very rough outline:

  • You can replace getc(file) with read(file,&c,1): just write a function which accepts the file as an argument and return a character. Read the character into a local ariable and return it.

  • Then implement a getline(file): Make a buffer, starting reading characters into it one at a time, stop when you come to '\n' (what will you do if you run out of room?), and return a pointer to the buffer (How can you allocate the buffer for this to work?).

  • Use you getline to read one line at a time, then write the line number and the line.

  • Loop until you run out of file...


To make fewer system calls:

Read the whole file into a large buffer in one go---that's pretty easy if you have the file size---and walk it one character at a time to find the line starts and ends (use two pointers).

You don't actually need to know the location of the '\n' to number the lines. You just print out the line number (starting with 1), and read characters until you hit a newline '\n'. Copy each character back to stdout with write(), and if the character is a newline, increment the count of current lines and print that out, too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top