#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
using std::string;
/*
* Read the next unit from standard input. Units are alternating all
* alphanumeric, or non-alphanumeric. No unit is empty; return the empty
* string to indicate end of input.
*/
std::string read_next(std::istream &strm)
{
// Read the first character. If none, we're done.
char firstch;
if(!strm.get(firstch)) return "";
// Result string. Starts with that first character.
string ret;
ret.push_back(firstch);
// Now, use the istream peek() method to add all immediately following
// characters of the same class
int nextch;
bool should_be_alnum = isalnum(firstch);
while((nextch = strm.peek()) != EOF) {
if(should_be_alnum == (bool)isalnum(nextch))
ret.push_back(strm.get());
else
break;
}
return ret;
}
/*
* Test method that reads the input stream and prints each item
* surrounded by []. Puts ten of them on a line, but some items contain
* line breaks.
*/
const int LIMIT = 10;
void handle(std::istream &strm)
{
string s;
int cnt = 0;
while((s = read_next(strm)) != "") {
std::cout << "[" << s << "]";
if(++cnt == LIMIT) {
cnt = 0;
std::cout << std::endl;
} else {
std::cout << " ";
}
}
}
/*
* Attempt to open a file and run the test on it.
*/
void run_on_file(string fn)
{
// Try to open a file to read.
std::ifstream in(fn);
if(!in) {
std::cout << "Cannot open " << fn << std::endl;
exit(1);
}
handle(in);
}
/*
* Read from a file named on the command line, requested from the user,
* or on standard input.
*/
int main(int argc, char **argv)
{
/*
* See where we're getting our data from
*/
if(argc > 1) {
// There seems to be a file name.
if(string(argv[1]) == "-" || string(argv[1]) == "") {
// Just read the standard input.
handle(std::cin);
} else {
// Read the file from the command line.
run_on_file(argv[1]);
}
} else {
// Ask for a file name and run there.
string fn;
std::cout << "What file to read? ";
std::getline(std::cin,fn);
run_on_file(fn);
}
}