I'm extremely new to C++ and I have an assignment to first format a name provided via the user, and then ensure it has proper capitalization (First letter capital, rest lowercase).
I feel like I have the function correct, but the function involves an array and the code I have written does not seem to allow a string to be initialized to the array.
The output of the first stretch of code is then input into the capitalize function and that is where I am running into an error.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void capitalize(char str[]);
int main()
{
//inputs user name in the format first, middle and last name
string name;
cout << "Enter your name in the order of first middle last: ";
getline(cin, name, '\n');
//string variables to extract the first. middle and last names
//from the input
string first, last, middle, subOutput;
// finds the poisiton of first space
int firstblank = name.find(' ', 0);
// taken as first name until the first space
first = name.substr(0, firstblank);
// finds second space
int secondblank = name.find(' ', firstblank + 1);
// if second space is not found means no middle name in the input
if (secondblank == -1)
{
// taken the remaining string as last name
last = name.substr(firstblank + 1);
// prepares name as desired output
subOutput = last + ", " + first;
}
else
{
// gets middle name from firstspace to second space
middle = name.substr(firstblank + 1, secondblank - firstblank - 1);
// gets last name
last = name.substr(secondblank + 1);
//prepares output
subOutput = last + ", " + first + " " + middle.at(0) + ".";
}
char O[] = subOutput;
capitalize(O);
cout << O << endl;
//displays output
//cout << O << endl;
return 0;
}
void capitalize(char str[]) {
if (strlen(str) == 0) {
return;
}
str[0] = toupper(str[0]);
for (int i = 1; i < strlen(str); i++)
{
str[1] = tolower(str[i]);
}
}
Might be a very basic fix but like I said, I am very new to coding/C++ so any help is greatly appreciated!
EDIT:
I actually revised my code and I believe I have some of the solution, however
there is a bug that I am unsure about.
New Code:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
const int CAPACITY = 1000;
void capitalize(string& str);
int main()
{
//inputs user name in the format first, middle and last name
//string variables to extract the first. middle and last names
string name, first, last, middle, subOutput, Output;
cout << "Enter your name in the order of first middle last: ";
getline(cin, name, '\n');
//from the input
// finds the poisiton of first space
int firstblank = name.find(' ', 0);
// taken as first name until the first space
first = name.substr(0, firstblank);
// finds second space
int secondblank = name.find(' ', firstblank + 1);
// if second space is not found means no middle name in the input
if (secondblank == -1)
{
// taken the remaining string as last name
last = name.substr(firstblank + 1);
// prepares name as desired output
subOutput = last + ", " + first;
}
else
{
// gets middle name from firstspace to second space
middle = name.substr(firstblank + 1, secondblank - firstblank - 1);
// gets last name
last = name.substr(secondblank + 1);
//prepares output
subOutput = last + ", " + first + " " + middle.at(0) + ".";
}
capitalize(subOutput);
Output = subOutput;
cout << Output << endl;
return 0;
}
void capitalize(string& str) {
if (str.length() == 0) {
return;
}
str[0] = toupper(str[0]);
for (int i = 1; i < str.length(); i++)
{
str[i] = tolower(str[i]);
}
}
The code compiles and formats properly, however when capitalizing, it only properly capitalizes the last name properly. I am not sure how I can get it to capitalize everything though. Like I said, any help is greatly appreciated!
Use to std::toupper(string[0]) to capitalise the first character. It's builtin function.
You are already using many of the std::basic_string functions, why not simply use the .begin() and .end() iterators and iterate over each character in the string keeping track of the last (previous) character seen and if the last character was whitespace (or a '.' indicating an initial), capitalize the current character, otherwise set to lowercase?
It is actually shorter and simpler. All of the std::basic_string functions are listed. All you need do is:
...
#include <cctype>
/* convert string to Titlecase */
void strtotitle (std::string& name)
{
char last = ' '; /* initialize last as whitespace */
for (std::string::iterator i = name.begin(); i != name.end(); i++) {
if (isspace(last) || last == '.')
*i = toupper(*i); /* convert 1st in word toupper */
else
*i = tolower(*i); /* convert remaining tolower */
last = *i; /* save current char as last */
}
}
Adding a short main() to take the users input you could do:
#include <iostream>
#include <string>
#include <cctype>
/* convert string to Titlecase */
void strtotitle (std::string& name)
{
char last = ' '; /* initialize last as whitespace */
for (std::string::iterator i = name.begin(); i != name.end(); i++) {
if (isspace(last) || last == '.')
*i = toupper(*i); /* convert 1st in word toupper */
else
*i = tolower(*i); /* convert remaining tolower */
last = *i; /* save current char as last */
}
}
int main (void) {
std::string name {};
std::cout << "enter name: ";
if (!getline (std::cin, name)) {
std::cerr << "(user canceled input)\n";
return 1;
}
strtotitle (name);
std::cout << "formatted : " << name << "\n";
}
It provides much more flexibility than searching manually for the first or second space, etc..
Example Use/Output
$ ./bin/name2title
enter name: alPHRED c. fudSTER
formatted : Alphred C. Fudster
or
$ ./bin/name2title
enter name: mICKEy mOUSe
formatted : Mickey Mouse
or
$ ./bin/name2title
enter name: m.m. disNey
formatted : M.M. Disney
You can also easily add an additional function to trim leading and trailing whitespace and compress multiple included whitespace to a single space allowing you to fully format even the strangest input.
Look things over and let me know if you have further questions.
When you are in c++. Why C-Styled char array. Library string has so m inbuilt function try them. Try this instead. C style arrays are often error-prone. Try to use C++ functions and libraries.
int main()
{
string s;
getline(cin,s);
decltype(s.size()) i = 0;
do{
if(i==0 || isspace(s[i-1]))
{
s[i] = toupper(s[i]);
}
else{
s[i] = tolower(s[i]);
}
++i;
}while(i!= s.size());
cout<<s;
return 0;}
comment if you found it hard to understand.
Related
I am currently self-studying C++ with Schaum's outline book (which covers mostly C contents, or so I've been told, but whatever) and I have encountered some trouble with problem 9.8.
You are supposed to count the number of appearances of every different word in a given c++ string, for which I assumed each word was separated from the next one by a white space, a newline or a dot or coma (followed in these two last cases by another white space).
My code is the following:
#include <iostream>
#include <string>
using namespace std;
int main()
{ string s;
cout << "Enter text (enter \"$\" to stop input):\n";
getline(cin,s,'$');
string s2 = s, word;
int ini = 0, last, count_word = 0;
int count_1 = 0, count_2 = 0, count_3 = 0;
cout << "\nThe words found in the text, with its frequencies, are the following:\n";
for (ini; ini < s.length(); )
{ // we look for the next word in the string (at the end of each iteration
// ini is incremented in a quantity previous_word.length()
last = ini;
cout << "1: " << ++count_1 << endl;
while(true)
{ if (s[last] == ' ') break;
if (s[last] == '\n') break;
if (s[last] == ',') break;
if (s[last] == '.') break;
if (last > s.length()-1 ) break;
++last;
cout << "2: " << ++count_2 << endl;
}
--last; // last gives the position within s of the last letter of the current word
// now me create the word itself
word = s.substr(ini,last-ini+1); //because last-ini is word.length()-1
int found = s2.find(word);
while( found != s2.length() ) // the loop goes at least once
++count_word;
s2.erase(0,found+word.length()); // we erase the part of s2 where we have already looked
found = s2.find(word);
cout << "3: " << ++count_3 << endl;
cout << "\t["<<word<<"]: " << count_word;
++last;
s2 = s;
s2.erase(0,ini + word.length()); // we do this so that in the next iteration we don't look for
// the new word where we know it won't be.
if (s[last] == ' ' || s[last] == '\n') ini = last + 1;
if (s[last] == ',' || s[last] == '.') ini = last + 2;
count_word = 0;
}
}
When I ran the program nothing was sshown on screen, so I figured out that one of the loops must had been stuck (that is why I defined the variables count_1,2 and 3, to know if this was so).
However, after correctly counting the number of iterations for the fist word to be found, nothing else is printed and all I see is the command prompt (I mean the tiny white bar) and I cannot even stop the program by using ctrl z.
This is a very complicated method for a very simple problem. You can just use a stringstream to extract each word seperated by a white space. You then just take the extracted word and increment the word counter using a std::map<std::string, int>.
My take on this:
#include <iostream>
#include <map>
#include <string>
#include <sstream>
int main() {
std::map<std::string, int> word_to_count;
std::string in;
std::getline(std::cin, in);
std::stringstream s(in);
std::string temp_word;
while (s >> temp_word) {
word_to_count[temp_word]++;
}
for (const auto& x : word_to_count) {
std::cout << x.first << ": " << x.second << std::endl;
}
return 0;
}
input
hello world hello world test
Output
hello: 2
test: 1
world: 2
Keep in mind this is just one of many possible solutions, so just take this as inspiration :).
My goal is to make a program that inputs a phone number and outputs it in a standard format. It skips over any non-number characters, will output if there are not enough digits, and will also skip over any digits after the first ten digits. My raptor worked without a hitch, but it's been difficult to translate it to C++.
I am using Microsoft Visual Studio.
The problem is it is not running. If I put in anything more then one number in, I receive a fail error.
I am having some difficulty running this code.
Any and all help and advice would be greatly appreciated.
#include <iostream>
#include <string>
using namespace std;
void format(char outArray[], string inNumber)
{
outArray[0] = '(';
outArray[4] = ')';
outArray[5] = ' ';
outArray[9] = '-';
outArray[1] = inNumber[0];
outArray[2] = inNumber[1];
outArray[3] = inNumber[2];
outArray[6] = inNumber[3];
outArray[7] = inNumber[4];
outArray[8] = inNumber[5];
outArray[10] = inNumber[6];
outArray[11] = inNumber[7];
outArray[12] = inNumber[8];
outArray[13] = inNumber[9];
}
int main()
{
string phone, inNumber;
cout << "Please enter a phone number: ";
cin >> phone;
int index = 0;
int num = 0;
char outArray[14];
for (index; phone[index] >= '0' && phone[index] <= '9'; index++)
{
inNumber[num] = phone[index];
num++;
}
if (inNumber.size() > 10)
{
format(outArray, inNumber);
cout << "The properly formatted number is: ";
cout << outArray;
}
else {
cout << "Input must contain at least 10 digits." << endl;
}
system("pause");
return 0;
}
A few things to note:
Use std::string instead array of char array.
You do not need to check charters using a for loop unless you are not sure about the input(phone). However, if that's the case, use std::getline() to get the input and parse as follows using a range-based for loop.
You can use std::isdigit to check the character is a digit.
My goal is to make a program that inputs a phone number and outputs it
in a standard format. It skips over any non-number characters, will
output if there are not enough digits, and will also skip over any
digits after the first ten digits.
That means the number should have a minimum length of 10. Then the
if statement should be if (inNumber.size() >= 10)
Need a pass by ref call in the function format(), since you want to change the content of outArray. Additionally, inNumber could be a
const ref, since we do not change this string.
Updated code: (See a sample code online)
#include <iostream>
#include <string>
#include <cstddef> // std::isdigit, std::size_t
void format(std::string& outArray, const std::string& inNumber) /* noexcept */
{
for (std::size_t index = 0; index < 10; ++index)
{
if (index == 0) outArray += '(';
else if (index == 3) outArray += ") ";
else if (index == 6) outArray += '-';
outArray += inNumber[index];
}
}
int main()
{
std::string phone;
std::cout << "Please enter a phone number: ";
std::getline(std::cin, phone);
std::string inNumber;
for (char letter : phone)
if (std::isdigit(static_cast<unsigned char>(letter))) // check the letter == digits
inNumber += letter;
if (inNumber.size() >= 10)
{
std::string outArray;
format(outArray, inNumber);
std::cout << "The properly formatted number is: ";
std::cout << outArray;
}
else {
std::cout << "Input must contain at least 10 digits." << std::endl;
}
return 0;
}
inNumber[num] = phone[index]; //undefined behavior.
You cannot subscript inNumber now, since its capacity is 0, thus it can not store or access any element here.
You may need to use string's constructor whose parameter has a size_t type or string::reserve or string::resize.
And I'm happy to see cppreference get more complete now, learn to use it: http://en.cppreference.com/w/cpp/string/basic_string
BTW, this function won't do anything you want to:
void format(char outArray[], string inNumber)
maybe you'd like to have an signature like this?
void format(char outArray[], string& inNumber)
For my code, I am trying to create a class with two functions that:
Display a cstring where each word is reversed
Display an entire cstring reversed
My two test sentences are "Hi There" and "To Be", so the output is:
erehT iH
eB oT
iH erehT
oT eB
Here is my code:
#include <iostream>
#include <cstring>
using namespace std;
class cStringType {
public:
char sentenceInput[80]; //Member variable
void reverse_sentence(); //Member function
void reverse_words(); //Member function
}; //Bottom of cStringType
int main()
{
cStringType sentence1, sentence2;
//Objects declared of cStringType
cout << "Please enter a sentence!\n" << endl;
cin.get(sentence1.sentenceInput, 79, '\n');
cin.ignore(80, '\n');
cout << "\nPlease enter another sentence!\n" << endl;
cin.get(sentence2.sentenceInput, 79, '\n');
cout << "\nThe first sentence reversed: ";
sentence1.reverse_sentence();
cout << endl;
cout << "The second sentence where each word is reversed: ";
sentence2.reverse_words();
cout << endl;
cout << endl;
cout << "The first sentence where each word is reversed: ";
sentence1.reverse_words();
cout << endl;
cout << "The second sentence reversed: ";
sentence2.reverse_sentence();
cout << endl;
return 0;
}
void cStringType::reverse_sentence()
{
char reverse_sentence;
//Reverse entire sentence using loop
for (int i = 0; i < strlen(sentenceInput) / 2; i++)
{
//Reverse the sentence using the length of the
//variable in the class
reverse_sentence = sentenceInput[i];
//First get the user input
//Set your variable equal to the variable in the class
sentenceInput[i] = sentenceInput[strlen(sentenceInput) - i - 1];
//Then reverse the characters and word order
//Starts from the last character in the array
//and goes backwards to 0
sentenceInput[strlen(sentenceInput) - i - 1] = reverse_sentence;
//Set the variable equal to the result
//sentenceInput is now the reverse of the user input in main
}
cout << sentenceInput << endl;
//Output of the new sentence
}
void cStringType::reverse_words()
{
int beginning, end, j = 0;
char reverse_words;
//Reverse each word separately using loop
for (int i = 0; i <= strlen(sentenceInput); i++)
//Get the length of the sentence in the class
{
if (sentenceInput[i] == ' ' || sentenceInput[i] == '\0')
//Check for spaces or null characters
//This allows only the letters of each word to be
//reversed, not the entire sentence
{
for (beginning = j, end = i - 1;
beginning < (i + j) / 2; beginning++, end--)
//j is the beginning of the array; increases
//i is the end of the array; decreases
{
reverse_words = sentenceInput[beginning];
//Set a variable equal to the first
//word in the original user input
sentenceInput[beginning] = sentenceInput[end];
//Set the first letter of a word equal to
//the last letter of a word
sentenceInput[end] = reverse_words;
//Set the result equal to the variable
//sentenceInput is now the user input where each
//word is reversed
}
}
j = i + 1;
}
cout << sentenceInput << endl;
//Output of the new sentence
}
When I try to run the code, the output becomes something like this:
Please enter a sentence!
Hi There
Please enter another sentence!
To Be
The first sentence reversed: erehT iH
The second sentence where each word is reversed: oT eB
The first sentence where each word is reversed: There Hi
The second sentence reversed: Be To
I tried fixing it, but to no avail. The output is never correct.
Is there some way to fix this issue? Or better yet, to simplify the code? I believe the issue is with the code in the function.
The main problem with your code is that it's using the same buffer for both transformations. In other words: you are reversing the words in the same string which you've already reversed entirely. So you need to have another copy of the original string to do these independently.
Regarding simplifying your code you need to define a function that would reverse a string given a pointer and size or begin and end pointers. Then you can use this function on your entire string or on every word you find while searching for a space character:
char *begin = sentenceInput; //points to the beginning of the word
char *end = sentenceInput + strlen(sentenceInput);
for (char *it = begin; it != end; ++it)
if (*it == ' ') {
reverse(begin, it);
begin = it + 1;
}
reverse(begin, end); //reverse the last word
The reverse function can be either std::reverse, which can be used in the above code and on the entire string as follows:
std::reverse(sentenceInput, sentenceInput + strlen(sentenceInput))
or you can create a similar function like this:
void reverse(char *begin, char *end)
{
--end; //point to the last character instead of one-past-last
while (begin < end)
std::swap(*begin++, *end--);
}
I would suggest using stack for it, it is a natural way of looking at it.
so
#include <stack>
and then the function would be like that
void cStringType::reverse_words()
{
int beginning, end, j = 0;
char reverse_words;
stack<char> lastWord;
//Reverse each word separately using loop
for (int i = 0; i <= strlen(sentenceInput); i++)
//Get the length of the sentence in the class
{
if (sentenceInput[i] == ' ' || sentenceInput[i] == '\0')
//Check for spaces or null characters
//This allows only the letters of each word to be
//reversed, not the entire sentence
{
//we want to print the last word that was parsed
while(!lastWord.empty())
{
//we print in the reverse order the word by taking off the stack char by char
cout<< lastWord.top();
lastWord.pop();
}
cout<<" ";
}
//if the letter is not space or end of string then push it on the stack
else
lastWord.push(sentenceInput[i]);
j = i + 1;
}
cout << sentenceInput << endl;
//Output of the new sentence
}
I am writing a C++ function that takes in a string of the form "let_varname_=_20" and then it will isolate "varname" to make a new string with my name variable name. I am trying to tell the .at() function to stop iterating through a while loop when it hits a space (the underscores are spaces, I just wanted it to be abundantly clear there was a space). However, it isn't comparing them properly, as it goes to the end of the string completely without stopping (passing by 2 spaces).
void store(std::string exp) {
int finalcount = 4;
char placeholder = ' ';
while (exp.at(finalcount)!=placeholder) {
finalcount++;
}
for (int i = 0; i < exp.size(); i++) {
std::cout << exp.at(i) << std::endl;
}
std::string varname = exp.substr(4, finalcount+1);
std::cout << finalcount + 1 << std::endl;
std::cout << varname << std::endl;
}
I started at index 4 because I know that indexes 0-3 of teh string will be 'l' 'e' 't' and ' '. The print statements were just me checking to see what it was reading versus what I input (and it was reading everything fine, just not comparing properly). I also tried have my while loop condition say while the char was >65 && <90 to work with ASCII codes but that also didn't work.
Thanks in advance for the help.
You could use istringstream and treat the string as a stream:
const std::string test_data = "let varname = 20";
std::istringstream test_stream(test_data);
std::string let_text;
std::string var_name;
char equals_sign;
unsigned int value;
test_stream >> let_text >> var_name >> equals_sign >> value;
This may be a lot easier than your code.
Edit 1: Searching the string
You could also use the std::string methods, find_first_of and find_first_not_of.
std::string::size_type position = test_data.find_first_of(' ');
position = test_data.find_first_not_of(' ', position);
std::string::size_type end_position = test_data.find_first_of(' ');
let_text = test_data.substr(position, end_position - position);
The problem is that you aren't using substr() properly, as I mentioned in a comment. Also, as Pete Becker mentioned in a comment, you should also be checking for = and stopping when you reach the end of the string, so that you don't overrun your string if there aren't any more spaces in it. Additionally, you don't want to add 1 to finalcount when determining substring length, because then your substring will include the space or = that made the check fail.
Try this:
void store(std::string exp) {
const int start = 4; // <-- Enter starting position here.
const char placeholder_space = ' '; // Check for space.
const char placeholder_equal = '='; // Check for equals sign, as pointed out by Pete Becker.
int finalcount = start; // <-- Use starting position.
bool found = false;
while (finalcount < exp.size() && !found) {
if (!((exp.at(finalcount) == placeholder_space) ||
(exp.at(finalcount) == placeholder_equal))) {
finalcount++;
} else {
found = true;
}
}
if (!found) {
std::cout << "Input is invalid.\n"; // No ' ' or '=' found, put error message here.
return;
}
for (int i = 0; i < exp.size(); i++) {
std::cout << exp.at(i) << std::endl;
}
std::string varname = exp.substr(4, finalcount - start); // <-- Use starting position.
std::cout << finalcount - start << std::endl; // Length of varname.
std::cout << varname << std::endl;
}
What is the best STL to use for this task? I've been using Map,
and I couldn't get it to work. I'm not sure how I am supposed to check the number of same words that occur in the sentence for example:
I love him, I love her, he love her.
So I want the program to prompt the user to enter an integer, lets say i enter 3, the output will be love as the same word occurs 3 times in the sentence. But what method to use if I want to do a program like this?
Currently my program prompts for the user to enter the word, and then it shall return how many time that word occurs, which for word love, is 3. but now i want it the other way round. Can it be done? Using which STL will be better?
I assume you use a map to store the number of occurrences.
Well,you first have to understand this,since you are using a map,the key is unique while the stored data may not be unique.
Consider a map, x
with contents
x["I"]=3
x["Love"]=3
x["C"]=5
There is unique a mapping from the key to the value,and not the other way round,if you want this one to one mapping ,i would suggest a different data structure.If you want to use map,and still search for an element,using STL search function or your own.Or you can write your search function.
search().
map<string,int>::iterator ser;
cin>>check;
for(ser=x.begin();ser!=x.end();++ser)
{
if(ser->second==check)
{
cout<<"Word"<<ser->first<<endl;
break;
}
}
First build the mapping from word to count and then build the reverse multi-mapping from that. Finally, you can determine which words occur with a given frequency:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <utility>
int main()
{
std::string str("I love him, I love her, he love her");
std::istringstream ss(str);
std::istream_iterator<std::string> begin(ss);
std::istream_iterator<std::string> end;
std::map<std::string, int> word_count;
std::for_each(begin, end, [&](const std::string& s)
{
++word_count[s];
});
std::multimap<int, std::string> count_words;
std::for_each(word_count.begin(), word_count.end(),
[&](const std::pair<std::string, int>& p)
{
count_words.insert(std::make_pair(p.second, p.first));
});
auto its = count_words.equal_range(3);
std::for_each(its.first, its.second,
[](const std::pair<int, std::string>& p)
{
std::cout << p.second << std::endl;
});
}
/******************************************************************
Name : Paul Rodgers
Source : HW1.CPP
Compiler : Visual C++ .NET
Action : Program will read in from standard input and determine the
frequency of word lengths found in input. An appropriate
table is also displayed. Maximum word length is 15 characters
words greater then 15 are counted as length 15.
Average word length also displayed.
Note : Words include hyphenated and ones with apostrophes. Words with
apostrophes, i.e. Jim's, will count the apostrophe as part of the
word length. Hyphen is counted if word on same line, else not.
Also an int array is used to hold the number of words with
length associated with matching subscript, with subscript 0
not being used. So subscript 1 corresponds to word length of 1,
subscript 2 to word length of 2 and so on.
------------------------------------------------------------------------*/
#include <iostream>
#include <ctype.h>
#include <iomanip>
using namespace std;
int NextWordLength(void); // function prototypes
void DisplayFrequencyTable(const int Words[]);
const int WORD_LENGTH = 16; // global constant for array
void main()
{
int WordLength; // actual length of word 0 to X
int NumOfWords[WORD_LENGTH] = {0}; // array holds # of lengths of words
WordLength = NextWordLength();
while (WordLength) // continue to loop until no word, i.e. 0
{ // increment length counter
(WordLength <= 14) ? (++NumOfWords[WordLength]) : (++NumOfWords[15]);
WordLength = NextWordLength();
}
DisplayFrequencyTable(NumOfWords);
}
/********************** NextWordLength ********************************
Action : Will determine the length of the next word. Hyphenated words and
words with apostrophes are counted as one word accordingly
Parameters : none
Returns : the length of word, 0 if none, i.e. end of file
-----------------------------------------------------------------------*/
int NextWordLength(void)
{
char Ch;
int EndOfWord = 0, //tells when we have read in one word
LengthOfWord = 0;
Ch = cin.get(); // get first character
while (!cin.eof() && !EndOfWord)
{
while (isspace(Ch) || ispunct(Ch)) // Skips leading white spaces
Ch = cin.get(); // and leading punctation marks
if (isalnum(Ch)) // if character is a letter or number
++LengthOfWord; // then increment word length
Ch = cin.get(); // get next character
if ((Ch == '-') && (cin.peek() == '\n')) //check for hyphenated word over two lines
{
Ch = cin.get(); // don't count hyphen and remove the newline char
Ch = cin.get(); // get next character then on next line
}
if ((Ch == '-') && (isalpha(cin.peek()))) //check for hyphenated word in one line
{
++LengthOfWord; // count the hyphen as part of word
Ch = cin.get(); // get next character
}
if ((Ch == '\'') && (isalpha(cin.peek()))) // check for apostrophe in word
{
++LengthOfWord; // count apostrophe in word length
Ch = cin.get(); // and get next letter
}
if (isspace(Ch) || ispunct(Ch) || cin.eof()) // is it end of word
EndOfWord++;
}
return LengthOfWord;
}
/*********************** DisplayFrequencyTable **************************
Action : Will display the frequency of length of words along with the
average word length
Parameters
IN : Pointer to array holding the frequency of the lengths
Returns : Nothing
Precondition: for loop does not go beyond WORD_LENGTH
------------------------------------------------------------------------*/
void DisplayFrequencyTable(const int Words[])
{
int TotalWords = 0, TotalLength = 0;
cout << "\nWord Length Frequency\n";
cout << "------------ ----------\n";
for (int i = 1; i <= WORD_LENGTH-1; i++)
{
cout << setw(4) << i << setw(18) << Words[i] << endl;
TotalLength += (i*Words[i]);
TotalWords += Words[i];
}
cout << "\nAverage word length is ";
if (TotalLength)
cout << float(TotalLength)/TotalWords << endl;
else
cout << 0 << endl;
}
#include<iostream>
#include<string>
#include<vector>
#include<cstddef>
#include<map>
using std::cout;
using std::cin;
using std::string;
using std::endl;
using std::vector;
using std::map;
int main() {
cout << "Please enter a string: " << endl;
string str;
getline(cin, str, '\n');
size_t str_len = str.size();
cout << endl << endl;
size_t i = 0, j = 0;
bool pop = false;
map<string, int> myMap;
for (size_t k = 0; k < str_len-1; k++) {
if (((k == 0) && isalpha(str[0])) || (!(isalpha(str[k-1])) && isalpha(str[k])))
i = k;
if ( isalpha(str[k]) && !(isalpha(str[k+1])) ) {
j = k;
pop = true;
}
if ( (k == str_len-2) && isalpha(str[k+1]) ) {
j = k+1;
pop = true;
}
if ( (i <= j) && pop ) {
string tmp = str.substr(i, j-i+1);
cout << tmp << '\t';
myMap[tmp]++;
pop = false;
}
}
cout << endl << endl;
map<string, int>::iterator itr, end = myMap.end();
for (itr = myMap.begin(); itr != end; itr++)
cout << itr->first << "\t - - - - - \t" << itr->second << endl;
cout << endl;
return 0;
}