I recently started doing some competitive programming in C and one of my first requirements was a high-speed token reader (analogous to the java Scanner
class' next()
function). A few examples of input I am most likely to read are:
5
ccadd
bddcc
5 4 1
1 2 5
2 3 7
3 4 8
4 5 2
2 3
The integer/float inputs will be handled using atoi()
and atof()
, so all I need to develop is a function that will read words from stdin
. Here's the first prototype:
#define BUF_SIZE (1 << 10) // approx 2 KiB or 1024 chars
char* next_token() {
char* buf = malloc(BUF_SIZE * sizeof(char));
char cc;
// consume leading whitespaces
while (isspace(cc=getchar())) ;
buf[0] = cc;
int i=1;
int nofs = 1;
while (!isspace(cc=getchar())) {
if (i >= BUF_SIZE*nofs) {
// gracefully extend buffer size
nofs++;
buf = realloc(buf, BUF_SIZE*nofs*sizeof(char));
}
buf[i] = cc;
i++;
}
// trim buffer
buf = realloc(buf, (i+1)*sizeof(char));
buf[i] = '\0';
return buf;
}
int main() {
int T = atoi(next_token());
while (T-- > 0) {
char* word = next_token();
// more logic here
}
}
Two questions I had with this code are:
- Is this fast enough? I think the major bottleneck lies with the
realloc
at the end, where I trim the length. If it's not fast enough, please suggest some optimizations. - Is this compliant with how C is generally written? I'm coming from Java and have little experience with C code. I write some embedded C but that's closer to assembly than it is to this type of code.
Any further improvements are welcome.