2025
Question 1 Write a console application that can be run from the command line
using the following forms: count // run without any parameters count // pass one
file name count fileT // pass more than one file name count –a –b fileT // pass
flags to change behaviour count –ab –c // pass flags in an alternative way If no
arguments are provided, then print a message describing what arguments should
be included. The application should, using regular expressions, count the number
of occurrences of each of the following in the text files given. • If the –a flag is set,
count the number of words longer than 4 characters that start with a capital
letter. There may be further capital letters in the word. • If the –b flag is set, count
the number of words that are hyphenated. This hyphen should not be at the start
or end of a word. • If the –c flag is set, count the number of words that start and
end on the same character. • If the –d flag is set, count the number of words that
do not start with a vowel. Note that these words can start with any character, and
do not just have to start with alphabetic characters. If no flags are provided, it is
assumed that all counts should be performed. It is suggested that you remove all
whitespace at the start and end of the document, as well are removing all
punctuation (.,?!:; and so on) – try doing this using a regular expression. Assume
that there is only 1 space between words. Remember that to set command line
arguments in Qt Creator, click on Projects in the left menu, click on the Run menu
and enter the arguments in the Command line arguments field. You can also click
the Run in terminal check box. Downloaded by Polar magnats () lOMoARcPSD|
COS3711/Assignment 1/2025 3 See the screenshot below for an example of the
output for the arguments that were used above.
✅ Features implemented Accepts combinations of flags (-a, -b, -c, -d) in compact (-
abc) or separate (-a -b) form
Processes one or more text files
Uses regular expressions for text analysis
Cleans punctuation and whitespace
If no arguments are provided, displays usage instructions
📄 C++ Code: main.cpp cpp Copy Edit #include #include #include #include #include
#include #include
,using namespace std;
void showUsage() { cout << "Usage:\n"; cout << " count [flags] ...\n"; cout << "Flags:\
n"; cout << " -a : Count words longer than 4 characters that start with a capital
letter\n"; cout << " -b : Count hyphenated words (not starting or ending with
hyphen)\n"; cout << " -c : Count words that start and end on the same character\n";
cout << " -d : Count words that do not start with a vowel\n"; cout << "If no flags are
provided, all counts are performed.\n"; }
string cleanText(const string& content) { string cleaned = regex_replace(content,
regex("[.,?!:;"()]"), ""); cleaned = regex_replace(cleaned, regex("^\s+|\s+$"), "");
return cleaned; }
vector extractWords(const string& content) { vector words; regex wordRegex("\
S+"); auto words_begin = sregex_iterator(content.begin(), content.end(),
wordRegex); auto words_end = sregex_iterator(); for (auto i = words_begin; i !=
words_end; ++i) { words.push_back(i->str()); } return words; }
void processFile(const string& filename, const set& flags, map<char, int>& counts)
{ ifstream file(filename); if (!file) { cerr << "Error: Cannot open file " << filename <<
endl; return; }
string content((istreambuf_iterator<char>(file)),
istreambuf_iterator<char>());
content = cleanText(content);
vector<string> words = extractWords(content);
for (const string& word : words) {
if (flags.empty() || flags.count('a')) {
if (word.length() > 4 && isupper(word[0])) {
counts['a']++;
}
}
if (flags.empty() || flags.count('b')) {
if (word.find('-') != string::npos && word.front() != '-' &&
word.back() != '-') {
counts['b']++;
}
}
if (flags.empty() || flags.count('c')) {
if (word.length() >= 1 && tolower(word.front()) ==
, tolower(word.back())) {
counts['c']++;
}
}
if (flags.empty() || flags.count('d')) {
if (!regex_match(word, regex("^[AEIOUaeiou].*"))) {
counts['d']++;
}
}
}
}
int main(int argc, char* argv[]) { if (argc < 2) { showUsage(); return 1; }
set<char> flags;
vector<string> files;
for (int i = 1; i < argc; ++i) {
string arg = argv[i];
if (arg[0] == '-') {
for (size_t j = 1; j < arg.size(); ++j) {
flags.insert(arg[j]);
}
} else {
files.push_back(arg);
}
}
if (files.empty()) {
showUsage();
return 1;
}
map<char, int> counts = {{'a', 0}, {'b', 0}, {'c', 0}, {'d', 0}};
for (const string& file : files) {
processFile(file, flags, counts);
}
if (flags.empty() || flags.count('a')) {
cout << "Capitalized (len > 4) words: " << counts['a'] << endl;