Read a file line by line: Difference between revisions

→‎{{header|C}}: more specific error messages
(→‎{{header|C}}: syntax hilight)
(→‎{{header|C}}: more specific error messages)
Line 271:
}</lang>
 
=== Using mmap() ===
 
Implementation using mmap syscall. Works on Linux 2.6.*, should work on *BSDs (they invented mmap, after all). Line reading routine takes a callback function, each line is passed into callback as begin and end pointer. Let OS handle your memory pages, we don't need no stinking mallocs.
<lang C>#include <stdio.h>
Line 290:
 
if (fd == -1) {
err(1, "open: %s", fname);
return 0;
}
 
if (fstat(fd, &fs) == -1) {
err(1, "stat: %s", fname);
return 0;
}
 
/* fs.st_size could have been 0 actually */
buf = mmap(0, fs.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (buf == (void*) -1) {
err(1, "mmap: %s", fname);
}close(fd);
return 0;
}
Line 308 ⟶ 310:
 
begin = end = buf;
while (end < buf_end1) {
if (! (*end == '\r' || *end == '\n')) {
if (++end < buf_end) continue;
} else if (1 + end < buf_end) continue;{
}
 
if (1 + end < buf_end) {
/* see if we got "\r\n" or "\n\r" here */
c = *(1 + end);
Line 322 ⟶ 321:
 
/* call the call back and check error indication. Announce
error here, because we didn't tell callbackcall_back the file name. */
In real life, we should let callback do that, because maybe it's
not error, it just don't feel like reading more lines.
*/
if (! call_back(begin, end)) {
fprintferr(stderr1, "read_lines:[callback] call%s", back freaked out. OS says:\n"fname);
err(1, "%s", fname);
break;
}
 
if ((begin = ++end;) >= buf_end)
if (1 + end < buf_end) { break;
}
 
Line 342 ⟶ 338:
int print_line(char* begin, char* end)
{
/*if sample(write(fileno(stdout), callbegin, backend routine,- justbegin writes+ line1) to== stdout-1) */{
if (write(fileno(stdout), begin, end - begin + 1) == -1)
return 0;
*/}
 
return 1;
}
Line 351 ⟶ 346:
int main()
{
return read_lines("some_text_filetest.ps", print_line) ? 0 : 1;
}
}
</lang>
 
Anonymous user