I am studying the c++ primer book and doing exercise 5.14. The exercise is:
Write a program to read strings from standard input
looking for duplicated words. The program should find places in the input
where one word is followed immediately by itself. Keep track of the largest
number of times a single repetition occurs and which word is repeated. Print
the maximum number of duplicates, or else print a message saying that no
word was repeated. For example, if the input is
how now now now brown cow cow the output should indicate that the word now occurred three times.
My code is as follow:
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
string pre_word, word, max_repeate_word;
int repeate_times = 0; max_repeate_times = 0;
while (cin >> word) {
if (word == pre_word) {
++repeat_times;
}
else {
repeat_times = 1;
pre_word = word;
}
if (max_repeat_times < repeat_times) {
max_repeat_times = repeat_times;
max_repeat_word = pre_word;
}
}
if (max_repeat_times <= 1) {
cout << "no word was repeated" << endl;
}
else {
cout << "the word '" << max_repeat_word << "' occurred " << max_repeat_times << " times" << endl;
}
}
Is there anything wrong with my code? The program does not show any output when I input any string.
while (cin >> word)
This stop only with EOF, you need to add a stop condition.
Example:
while (cin >> word && word != "")
Related
If I type john when prompted for a char, the while statement will loop 4 times, one for each letter of john, before it asks again for user input.
Why does this program do not allow me insert more input before the whole 4 chars of john are consumed ? I would expect it to discard the 3 remaining letters of the string john and asked me for more input on the second loop.
The whole example can be found at page 44 of Bjarne Stroustrup The C++ Programming Language 4th edition.
#include <iostream>
using namespace std;
bool question() {
while (true) {
cout << "Continue ?\n";
char answer = 0;
cin >> answer;
cout << "answer: " << answer << endl;
}
return false;
}
int main () {
cout << question() << endl;
}
The output becomes:
Continue ?
john
answer: j
Continue ?
answer: o
Continue ?
answer: h
Continue ?
answer: n
Continue ?
You may be wondering why you're not being allowed to enter a character at each prompt. You have entered four characters into the input stream, so your loop runs four times to consume all of that input.
If you only want to use the first character in the input, you may want to get an entire line and work on just the first character.
#include <iostream>
#include <string>
bool question() {
while (true) {
std::cout << "Continue ?\n";
std::string line;
std::getline(std::cin, line);
std::cout << "answer: " << line[0] << endl;
}
return false;
}
Of course, you should also check that an empty line was not entered, which may be as simple as checking if line[0] is not '\0'.
I need to write a sentence in Pig Latin form and I am almost done it successfuly except for 1 case and I almost give up
for example :
If my word starts at a\e\o\u\i the word will look like easy -> easyway , apple -> appleway
and if it doesnt start with a letter that I wrote above
it will look like that: box -> oxbay , king -> ingkay
I succeed with the bolded part but in the first part with a\e\o\u\i letter at the beginning , I dont know where to put the w before and need some help with it
This is my code , thanks in advance
#include <iostream>
//Since those are used in ALL function of program, it wont hurt to set it to global
//Else it is considered EVIL to declare global variables
const int maxLine = 100;
char phraseLine[maxLine] = { '\0' };
void pigLatinString();
using namespace std;
void main()
{
// Displayed heading of program
cout << "* You will be prompted to enter a string of *" << endl;
cout << "* words. The string will be converted into *" << endl;
cout << "* Pig Latin and the results displayed. *" << endl;
cout << "* Enter as many strings as you would like. *" << endl;
//prompt the user for a group of words or press enter to quit
cout << "Please enter a word or group of words. (Press enter to quit)\n";
cin.getline(phraseLine, 100, '\n');
cout << endl;
// This is the main loop. Continue executing until the user hits 'enter' to quit.
while (phraseLine[0] != '\0')
{
// Display the word (s) entered by the user
cout << "You entered the following: " << phraseLine << endl;
// Display the word (s) in Pig Latin
cout << "The same phrase in Pig latin is: ";
pigLatinString();
cout << endl;
//prompt the user for a group of words or press enter to quit
cout << "Please enter a word or group of words. (Press enter to quit)\n";
cin.getline(phraseLine, 100, '\n');
}
return;
}
void pigLatinString() //phraseLine is a cstring for the word, maxline is max length of line
{ //variable declarations
char tempConsonant[10];
tempConsonant[0] = '\0';
int numberOfConsonants = 0;
char previousCharacter = ' ';
char currentCharacter = ' ';
bool isInWord = 0;
// for loop checking each index to the end of whatever is typed in
for (int i = 0; i < maxLine; i++)
{
//checking for the end of the phraseline
if (phraseLine[i] == '\0')
{//checking to see if it's in the word
if (isInWord)
{//checking to see that there wasn't a space ahead of the word and then sending the cstring + ay to the console
if (previousCharacter != ' ')
cout << tempConsonant << "ay" << endl;
}
return;
}
// this covers the end of the word condition
if (isInWord)
{// covers the condition of index [i] being the space at the end of the word
if (phraseLine[i] == ' ')
{
// spits out pig latin word, gets you out of the word, flushes the temp consonants array and resets the # of consonants to 0
cout << tempConsonant << "ay";
isInWord = 0;
tempConsonant[0] = '\0';
numberOfConsonants = 0;
}
cout << phraseLine[i] ;
}
else
{//this covers for the first vowel that makes the switch
if (phraseLine[i] != ' ')
{// sets the c string to what is in the phraseline at the time and makes it capitalized
char currentCharacter = phraseLine[i];
currentCharacter = toupper(currentCharacter);
// this takes care of the condition that currentCharacter is not a vowel
if ((currentCharacter != 'A') && (currentCharacter != 'E') &&
(currentCharacter != 'I') && (currentCharacter != 'O') && (currentCharacter != 'U'))
//this sets the array to temporarily hold the consonants for display before the 'ay'
{//this sets the null operator at the end of the c string and looks for the next consonant
tempConsonant[numberOfConsonants] = phraseLine[i];
tempConsonant[numberOfConsonants + 1] = '\0';
numberOfConsonants++;
}
else
{// this sets the boolean isInWord to true and displays the phraseline
isInWord = 1;
cout << phraseLine[i];
}
}
else
{
cout << phraseLine[i] ;
}
}
previousCharacter = phraseLine[i];
}
return;
}
You have two conditions to consider. if your word starts with a vowel, just add "way" to the end of the word, else move the first letter and add "ay" to the end.
This is a task that can be made a lot simpler by using std::string instead of C-strings. This is because you are now no longer concerned with exceeding your length or losing the null character. It also allows easier access to the Standard Library algorithms.
#include <algorithm>
#include <iostream>
#include <string>
std::string make_pig_latin(const std::string& word) {
std::string vowels("aeiou");
std::string newWord(word);
if (newWord.find_first_not_of(vowels) == 0) {
// Word starts with a consanant
std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
newWord += "ay";
} else {
newWord += "way";
}
return newWord;
}
int main() {
std::cout << make_pig_latin("apple") << '\n'
<< make_pig_latin("box") << '\n'
<< make_pig_latin("king") << '\n'
<< make_pig_latin("easy") << '\n';
}
The function above highlights how you can go about structuring your conversion. You just need to know if your word starts with a vowel or not, and take the appropriate action.
Output:
appleway
oxbay
ingkay
easyway
I did not get the impression that you have to care about words like 'phone'.
Looking through your code, you should try to do a better job at separating your concerns. Pig Latin is easier done one word at a time, but you have string splitting code and a lot of "not Pig Latin" code in your Pig Latin function. Your main can handle getting input. You should probably have a separate function to break the line up into individual words, using std::vector to hold the words would be best since it can grow on demand and doesn't have to know a specific capacity up front. You then iterate through your array of words and translate them individually. Depending on what your actual requirements are, it's possible that you don't even have to store the translated words, just print them directly to the screen.
Here's the same program, but now it can separate words. Note how the pig latin function doesn't have to change (much, I added upper-case vowels just because I didn't want to bothered converting words) in order for the added functionality to be added.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
std::string make_pig_latin(const std::string& word) {
std::string vowels("aeiouAEIOU");
std::string newWord(word);
if (newWord.find_first_not_of(vowels) == 0) {
// Word starts with a consanant
std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
newWord += "ay";
} else {
newWord += "way";
}
return newWord;
}
int main() {
std::string phrase(
"A sentence where I say words like apple box easy king and ignore "
"punctuation");
std::istringstream sin(phrase);
std::vector<std::string> words(std::istream_iterator<std::string>(sin), {});
for (auto i : words) {
std::cout << make_pig_latin(i) << ' ';
}
}
Output:
Away entencesay hereway Iway aysay ordsway ikelay appleway oxbay easyway ingkay andway ignoreway unctuationpay
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 :).
So I'm just starting in C++, so I'm not familiar with the language, though I do have knowledge of C. I'm trying to print words vertically. Here is the problem given.
Create an array of 25 strings.
Use a sentinel loop that reads from cin until the array is full or the end of input is reached
(when the user presses Ctrl-D), whichever comes first.
After the sentinel loop is over, use a for loop to move through the array.
Remember not to travel farther than the last array element that was input.
Print one array element (one string) followed by a newline
Use a for loop to move through the characters of the string you just printed
print one character followed by a newline
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
char word;
int count = 0;
cout << "Enter a word: (press Ctrl-D to quit)";
cin >> word;
int array1[25];
while (!cin.eof())
{
count = count + 1;
cout << "Enter a word: (press Ctrl-D to quit)";
cin >> word;
} //end while
for (word = 0; word <= array1[count]; word++)
{
cout << 'end1' << 'end1' << "There were " << count << "Words Entered" << 'end1';
}
} //end main
Code is rough, it compiles, but when it is in an infinite loop with numbers comes out after the texts.
Just for the hell of it
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
string word;
int count = 0;
vector<string> arrayOfStrings;
cout << "Enter a word: (press Ctrl-D to quit)";
while(cin >> word){
if(count < 25){
arrayOfStrings.push_back(word);
count = count + 1;
cout << "Enter a word: (press Ctrl-D to quit)";
} else {
cout << "25 strings was entered";
break;
}
}//end while
for ( int j = 0; j < arrayOfStrings.size(); j++ ){
cout << '\n' << '\n' << $j << "-st string entered " << arrayOfStrings[j] << '\n';
}
}//end main
This code reads exactly 25 strings, remembers them, and even outputs them later.
This is just an educational example, which basically ignores memory managment
I strongly suggest not to use this in any actual code.
It took me about 5 mins to write this.
There are a few errors in this code - perhaps if you are familiar with C, then quickly write a version in C and translate it to a more modern "C++ like" version. Perhaps look into std::string and std::vector to make life even easier.
int array1[25]; needs to store strings, therefore it is of the wrong type.
The while (!cin.eof()) loop needs to also check that it doesn't go over the bounds of the above array (i.e. at most 25 words).
The for (word = 0; word <= array1[count]; word++) loop that needs to loop exactly n times, where n is the number of words inputted, i.e. in the above while loop.
I'm reading c++ primer 5th and I have a little problem with an exercise:
Read a sequence of words from cin and store the values a vector. After
you’ve read all the words, process the vector and change each word to
uppercase. Print the transformed elements, eight words to a line.
My code is this:
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
using std::vector;
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main(){
vector<string> words;
string wordBuffer;
vector<string> output(1);
while (cin >> wordBuffer){
words.push_back(wordBuffer);
}
for (string &word : words){
for (char &letter : word){
letter = toupper(letter);
}
}
unsigned currentLine = 0;
for (decltype(words.size())index = 0; index < words.size(); ++index){
output[currentLine] += words[index] + " ";
if ((index+1) % 8 == 0){
++currentLine;
output.push_back("");
}
}
for (string s : output){
s[s.size() - 1] = 0; //removing the whitespace
cout << s << endl;
}
system("pause");
return 0;
}
Now, everything works well, but i have an issue with the input of the words by console.
If I write
I am writing a random words ^Z
and press Enter nothing happens. I have to rewrite the ^Z after I have pressed the Enter, like here:
I am writing a random words
^Z
Can you expain me why? Thanks!
PS: I'm saying that because in my previous programs writing ^Z in the same line worked fine. Like in this code:
#include <iostream>;
int main(){
int currval = 0,val = 0;
int count = 1;
while (std::cin >> val){
if (currval == val){
++count;
}
else {
std::cout << "The number " << currval << " appears " << count << " times" << std::endl;
currval = val;
count = 1;
}
}
std::cout << "The number " << currval << " appears " << count << " times" << std::endl;
system("pause");
return 0;
}
I can't figure out why :(
The ^Z has to be first in order for Windows to treat it as Ctrl+Z, otherwise it is just treated as meaningless characters.
If you would like it to work like you wrote i'd suggest:
String wordBuffer("")
while (strcmp(wordBuffer[strlen(wordBuffer)-3], "^Z") != 0){
words.push_back(wordBuffer);
cin >> wordBuffer
}
EDIT: in your second example it works because when you read integers c++ knows to divide the given string of numbers in the space (or ENTER if the numbers are entered separately in every line) to read every number separately so if you'll enter:
123 2323 4545 43 ^Z
It will read 123, then 2323, ... and then ^Z and so it will be as though it got it in a separate line but when you read string, it cant do that because a string contain every symbol and so it separate the input in the ENTER pressed and that why the second one works
As far as I know Ctrl+Z is placed in the keyboard buffer before any other entered symbols. Thus any entered characters before Ctrl+Z will be discarded. You need to do the following
I am writing a random words ENTER
^Z ENTER