#include #include #include #include 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); } }