Skip to content

Instantly share code, notes, and snippets.

@jdmichaud
Last active March 26, 2017 16:34
Show Gist options
  • Save jdmichaud/f2c454942bbb6038fa909a9453c8d395 to your computer and use it in GitHub Desktop.
Save jdmichaud/f2c454942bbb6038fa909a9453c8d395 to your computer and use it in GitHub Desktop.
word counting
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <inttypes.h>
#include <ctype.h>
#define BUF_LEN 16384
int main(int argc, char **argv) {
int fd;
char buffer[BUF_LEN];
uint64_t count = 0;
uint64_t lcount = 0;
uint64_t ccount = 0;
uint64_t wcount = 0;
ssize_t rcount = 0;
if (argc < 2) {
fd = STDIN_FILENO;
} else {
fd = open(argv[1], O_RDONLY);
}
if (fd < 0) {
fprintf(stderr, "Can't open file\n");
return 1;
}
#if __linux__ || __unix__
posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
#endif
rcount = read(fd, buffer, BUF_LEN);
ccount += rcount;
while (rcount-- > 0) {
if (buffer[rcount] == '\n') lcount++;
if (isspace(buffer[rcount])) {
if (count) {
count = 0;
++wcount;
}
} else ++count;
if (rcount == 0) {
rcount = read(fd, buffer, BUF_LEN);
if (ccount > 0) ccount += rcount;
}
}
if (count) ++wcount;
fprintf(stdout, " %" PRIu64 " %" PRIu64 " %" PRIu64 " %s\n",
lcount, wcount, ccount, (fd != STDIN_FILENO ? argv[1] : ""));
return 0;
}
use std::env;
use std::io::{self, Read};
use std::fs::File;
fn count<T: Read>(input: &mut T, ccount: &mut u64, lcount: &mut u64, wcount: &mut u64) -> () {
let mut buffer = [0; 16384];
let mut count = 0;
let mut rcount = input.read(&mut buffer).unwrap();
*ccount += rcount as u64;
while rcount > 0 {
rcount -= 1;
if buffer[rcount] == '\n' as u8 { *lcount += 1; }
if (buffer[rcount] as char).is_whitespace() {
if count > 0 {
count = 0;
*wcount += 1;
}
} else { count += 1; }
if rcount == 0 {
rcount = input.read(&mut buffer).unwrap();
*ccount += rcount as u64;
}
}
if count > 0 { *wcount += 1; }
}
fn main() {
let mut ccount = 0;
let mut lcount = 0;
let mut wcount = 0;
let (nargs, _) = env::args().size_hint();
if nargs >= 2 {
let filename = env::args().nth(1).expect("Error: No argument provided");
let mut file = File::open(&filename).expect("Can't open file");
count(&mut file, &mut ccount, &mut wcount, &mut lcount);
println!("{} {} {} {}", lcount, wcount, ccount, filename);
} else {
count(&mut io::stdin(), &mut ccount, &mut wcount, &mut lcount);
println!("{} {} {}", lcount, wcount, ccount);
}
()
}
@jdmichaud
Copy link
Author

As fast as linux wc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment