I am making a random username generator and I am having issues with printing numbers after the randomly selected vector item.
Code:
#include <iostream>
#include <cassert>
#include <vector>
#include <fstream>
using namespace std;
int main () {
// Initialize
srand (time(NULL));
int length = 0, quantity = 0, random = 0;
// Prompt & Introduce user
cout << "Random Username Generator!" << endl;
cout << "Enter word length, 0 for random: ";
cin >> length;
cout << "How many words?: ";
cin >> quantity;
// Read in dictionary textfile
ifstream fin;
fin.open( "CSW_2019.txt" );
assert( fin.is_open() );
// Initialize vector
vector<string> validWords;
string word = "";
// Loop to build validWords vector
while ( !fin.eof() ) {
getline(fin, word);
if ( word.length()-1 == length || length == 0 ) {
validWords.push_back(word);
}
}
// Loop to randomly display words and 1-2 digits following
for ( int i = 0; i < quantity; i++ ) {
// Random in-range value
random = rand() % validWords.size();
// Print random word
cout << validWords[random] << flush;
// Print number between 0 and 99
cout << random % 100 << endl;
}
// Close file because I wasn't raised in a barn
fin.close();
}
Output:
Random Username Generator!
Enter word length, 0 for random: 4
How many words?: 4
92IN
24RE
92PS
31OR
My question is NOT about how to print a c++ vector, because it is simple. My question is seeking understanding for the strange printing output.
Here is an example of output that does not implement the line cout << random % 100 << endl; and changes the above << flush; to << endl; instead.
Output (not implementing numbers):
Random Username Generator!
Enter word length, 0 for random: 4
How many words?: 4
DOLT
RAYS
MOLE
BELT
Any and all help is appreciated, thank you all in advance.
Related
i new to programming and we are required to create a program that dont exit when the user inputs the wrong input, but i only learned the basics so far.. i already solved when the number is above and below 100 but when the user accidentally inserted a non integer it will go into a error loop. btw this is an average calculator.
#include <iostream>
using namespace std;
int main()
{
int num[100];
int n;
double sum, average;
cout << "how many numbers will you input?: ";
cin >> n;
while ( n > 100 || n <= 0 )
{
cout << "Error! number should in range of (1 to 100) only." << endl;
cout << "Enter the number again: ";
cin >> n;
}
for ( int i = 0; i < n; ++i )
{
cout << i + 1 << ". Enter number: ";
cin >> num[i];
sum += num[i];
}
average = sum / n;
cout << "Average = " << average;
}
If std::istream::operator >> fails, it will set failbit. Therefore, you should check failbit (for example by calling std::cin.fail()) to see whether the conversion was successful, before using the result of the conversion.
If the conversion fails due to bad input, then the next call to std::istream::operator >> will automatically fail due to failbit being set. That is why you are getting stuck in an infinite loop. If you want to attempt input again after a conversion failure, you will first have to clear failbit, by using the function std::cin.clear().
Also, you will have to discard the bad input that caused the conversion to fail, because otherwise, the next time you call std::istream::operator >>, the conversion will fail again for the same reason. In order to clear the bad input, you can use std::cin.ignore(), like this:
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
In order to use std::numeric_limits, you will have to #include <limits>.
After performing these fixes on your code, it should look like this:
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int num[100];
int n;
double sum, average;
bool input_ok;
//repeat until input is valid
do
{
cout << "How many numbers will you input? ";
cin >> n;
if ( cin.fail() )
{
cout << "Error: Conversion to integer failed!\n";
input_ok = false;
}
else if ( n > 100 || n <= 0 )
{
cout << "Error: Number should in range of (1 to 100) only!\n";
input_ok = false;
}
else
{
input_ok = true;
}
//clear failbit
cin.clear();
//discard remainder of line
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
} while ( !input_ok );
for ( int i = 0; i < n; ++i )
{
do
{
cout << i + 1 << ". Enter number: ";
cin >> num[i];
if ( cin.fail() )
{
cout << "Error: Conversion to integer failed!\n";
input_ok = false;
}
else
{
input_ok = true;
}
//clear failbit
cin.clear();
//discard remainder of line
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
} while ( !input_ok );
sum += num[i];
}
average = sum / n;
cout << "Average = " << average;
}
This program has the following behavior:
How many numbers will you input? 200
Error: Number should in range of (1 to 100) only!
How many numbers will you input? -31
Error: Number should in range of (1 to 100) only!
How many numbers will you input? test
Error: Conversion to integer failed!
How many numbers will you input? 4abc
1. Enter number: 1
2. Enter number: 2
3. Enter number: 3
4. Enter number: 4
Average = 2.5
As you can see, the program now works in that it can now handle bad input such as test. It rejects that input and reprompts the user for new input.
However, one problem with this program is that it accepts 4abc as valid input for the number 4. It would probably be appropriate to reject such input instead. One way to fix this would be to inspect the remainder of the line, instead of simply discarding it.
Another issue is that this solution contains a lot of code duplication. Apart from the range check, both do...while loops are nearly identical. Therefore, it would be better to put this loop into a function, which can be called from several places in your code.
However, I generally don't recommend that you use std::istream::operator >>, because its behavior is not always intuitive. For example, as already pointed out above:
It does not always read a whole line of input, so that you must explicitly discard the remainder of the line.
It accepts 4abc as valid input for the number 4.
In my experience, if you want proper input validation of integer input, it is usually better to write your own function that reads a whole line of input using std::getline and converts it with std::stoi. If the input is invalid, then the function should automatically reprompt the user.
In my example below, I am calling this function get_int_from_user.
If you want to additionally ensure that the input is in a certain range, then you can call the function get_int_from_user in an infinite loop, and break out of that loop once you determine that the input is valid.
#include <iostream>
#include <string>
#include <sstream>
#include <cctype>
int get_int_from_user( const std::string& prompt );
int main()
{
int nums[100];
int n;
double sum;
//repeat loop forever, until input is good
for (;;) //equivalent to while(true)
{
n = get_int_from_user( "How many numbers will you input? " );
if ( 1 <= n && n <= 100 )
//input is good
break;
std::cout << "Error! Number should in range of (1 to 100) only.\n";
}
//read one number per loop iteration
for( int i = 0; i < n; i++ )
{
std::ostringstream prompt;
prompt << "Enter number #" << i + 1 << ": ";
nums[i] = get_int_from_user( prompt.str() );
sum += nums[i];
}
std::cout << "Average: " << sum / n << '\n';
}
int get_int_from_user( const std::string& prompt )
{
std::string line;
std::size_t pos;
int i;
//repeat forever, until an explicit return statement or an
//exception is thrown
for (;;) //equivalent to while(true)
{
//prompt user for input
std::cout << prompt;
//attempt to read one line of input from user
if ( !std::getline( std::cin, line ) )
{
throw std::runtime_error( "unexpected input error!\n" );
}
//attempt to convert string to integer
try
{
i = std::stoi( line, &pos );
}
catch ( std::invalid_argument& )
{
std::cout << "Unable to convert input to number, try again!\n";
continue;
}
catch ( std::out_of_range& )
{
std::cout << "Out of range error, try again!\n";
continue;
}
//The remainder of the line is only allowed to contain
//whitespace characters. The presence of any other
//characters should cause the entire input to get rejected.
//That way, input such as "6sdfj23jlj" will get rejected,
//but input with trailing whitespace will still be accepted
//(just like input with leading whitespace is accepted by
//the function std::stoi).
for ( ; pos < line.length(); pos++ )
{
if ( !std::isspace( static_cast<unsigned char>(line[pos]) ) )
{
std::cout << "Invalid character found, try again!\n";
//we cannot use "continue" here, because that would
//continue to the next iteration of the innermost
//loop, but we want to continue to the next iteration
//of the outer loop
goto continue_outer_loop;
}
}
//input is valid
return i;
continue_outer_loop:
continue;
}
}
This program has the following behavior:
How many numbers will you input? 200
Error! Number should in range of (1 to 100) only.
How many numbers will you input? -31
Error! Number should in range of (1 to 100) only.
How many numbers will you input? test
Unable to convert input to number, try again!
How many numbers will you input? 4abc
Invalid character found, try again!
How many numbers will you input? 4
Enter number #1: 1
Enter number #2: 2
Enter number #3: 3
Enter number #4: 4
Average: 2.5
As you can see, it now correctly rejects the input 4abc.
I believe that using the function get_int_from_user makes the code in main much cleaner.
Note that the code above uses one goto statement. Under most circumstances, you should avoid using goto, but for breaking out of nested loops, it is considered appropriate.
#include <iostream>
#include <limits>
using namespace std;
int avg(int sum, int n)
{
int average;
average = sum/n;
cout<<"Avg = "<<average;
}
int main()
{
int n;
cout << "how many numbers will you input?: ";
cin >> n;
int w = n;
int num[w];
int sum;
while(n>100||n<=0)
{
cout << "Error! number should in range of (1 to 100) only." << endl;
cout << "Enter the number again: ";
cin >> n;
}
for(int i = 0; i < n; ++i)
{
cout << i + 1 << "Enter number: ";
cin >> num[i];
if(!cin)
{
cout << "Wrong Choice. " << endl;
cin.clear();
cin.ignore( numeric_limits<std::streamsize>::max(), '\n' );
n++;
continue;
}
else
{
sum += num[i];
}
}
cout<<"Sum = "<<sum<<endl;
avg(sum,w);
}
I'm creating a piece of code which is supposed to simulate a guessing game in which I pull a random line from a text file, in this example "premier league football teams", then I have to take the random line and have it convert into the corresponding numbers in the alphabet, so in the example of "arsenal" I would have to output "1 18 19 5 14 1 12". as this is a game the user has to guess that the numbers mean "arsenal" and then type that in to gain a point and continue. so far I have been able to code a method of pulling a random line from the file, however I am unsure how I would be able to then convert that code into numbers without outputting the answer, as this is meant to be a guessing game.
this is the relevant section of text, but to keep this short I will not paste the full code
vector<string> lines;
srand(time(NULL));
//ensures random selection on each new code run
ifstream file("Premier_League_Teams.txt");
//pulls the file from the directory
int total_lines = 0;
while (getline(file, line))
//this function counts the number of lines in a text file
{
total_lines++;
lines.push_back(line);
}
int random_number = rand() % total_lines;
//selects a random entry from the text file
//end of adapted code
cout << lines[random_number];
I am assuming that I will have to do a switch statement, but I do not know how to apply that case statement to the randomly selected line, and then have the user input the plain english text
NEW CODE WITH HELP FROM COMMENTS
#include <fstream>
//fstream included to pull answers from category files
#include <string>
#include <vector>
#include <list>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
cout << "Richard Osman's house of Games: This round is in code.\n\n\n";
cout << "The objective of this round is to unscramble the coded word, you will be given the category as the clue and you have to type out what you belive the answer to be, with a capital letter\n\n";
cout << endl;
string Name;
cout << "But First, Enter your first name.\n";
cin >> Name;
cout << "Welcome contestant " << Name << " Are you ready to begin the quiz?\n";
// this is to add a level of immersion to the game, by allowing the code to recall the players name so that they have a personalised experience
string respond;
cout << "please type Yes or No (case sensitive).\n";
cin >> respond;
if (respond == "Yes")
{
cout << "\nGood luck!";
}
else
{
cout << "Maybe next time!";
return 0;
}
{ cout << "The first category is..." << endl;
cout << "Premier League Football Teams!" << endl;
//code adapted from Ranjeet V, codespeedy
string line;
vector<string> lines;
srand(time(NULL));
//ensures random selection on each new code run
ifstream file("Premier_League_Teams.txt");
//pulls the file from the directory
int total_lines = 0;
while (getline(file, line))
//this function counts the number of lines in a text file
{
total_lines++;
lines.push_back(line);
}
int random_number = rand() % total_lines;
//selects a random entry from the text file
//end of adapted code
int random_number = 0;
vector<string> lines;
lines.push_back("abc arsenal");
string alpha = "abcdefghijklmnopqrstuvwxyz";
string word = lines[random_number];
//line from lines vector for which we will calculate numbers
int* codes;
codes = new int[word.length()];
//array in which we will store codes for letters
for (int i = 0; i < word.length(); i++) {
//iterate over each characte of string word
if (word[i] != ' ')
//as we dont want to replace spaces with numbers or somethings, but it will automatically become 0 as it is default
codes[i] = alpha.find(word[i]) + 1;
//assign codes correspoding element to (index of char)+1
}
for (int i = 0; i < word.length(); i++) {
if (codes[i] == 0) {
continue;
//do not print codes' element if it is zero because it will become zero for spaces
}
cout << codes[i] << " ";
//outputting each codes element with a space in between
}
You can declare a string like
std::string alphabet="abcdefghijklmnopqrstuvwxyz"; and then for particular character if you want to find the equivalent position number you can use str.find(char); to get index of char in str and then add one to get its position number.
For eg;
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
int random_number=0;
vector<string> lines;
lines.push_back("abc arsenal");
string alpha="abcdefghijklmnopqrstuvwxyz";
string word=lines[random_number]; //line from lines vector for which we will calculate numbers
int* codes;
codes=new int[word.length()]; //array in which we will store codes for letters
for(int i=0;i<word.length();i++) { //iterate over each characte of string word
if(word[i]!=' ') //as we dont want to replace spaces with numbers or somethings, but it will automatically become 0 as it is default
codes[i]=alpha.find(word[i])+1; //assign codes correspoding element to (index of char)+1
}
for(int i=0;i<word.length();i++) {
if(codes[i]==0) {
continue; //do not print codes' element if it is zero because it will become zero for spaces
}
cout<<codes[i]<<" "; //outputting each codes element with a space in between
}
}
[Note] : Just for example I have assigned random_number to 0 and made a sample vector lines so that you can have more clarity on how to use this method in your case.
the char datatype have a numerical value and are displayed as a character. We make use of this!
Lowercase a = 97, lowercase b = 98, etc. So if you subtract 96 and then cast it to an interger using (int), you will be all set :)
So I have a program here that is supposed to print to the screen permutations of a user input word that can be 4 to 10 characters long and there are supposed to be as many permutations as there are letters in the word. I almost have complete success, but there is one issue. When it prints the permutations, after the first about 2 permutations, it starts to not use all the letters and/or the same letter twice.
For example, if the user input word is "bill", the output is as follows:
llib illb ibll lbii
The fourth is is obviously not correct. The problem is more apparent with words that have more letters. I need it to only use the letters it has once. How do I go about fixing this in my code? Here is my code.
int main(void)
{
string word;
string randword;
string reverse;
int length;
int i = 0;
int j = 0;
string randCH;
cout << "Enter any word 4 to 10 letters in length: ";
cin >> word;
//Checks if word is less than 4 or greater than 10
while (1)
{
/*The code here is in the final program and I know it works. The problem is not here*/
}
length = word.length();
//Uses reverse function
reverse = reverseit(word);
/*reverseit is a function outside of main that makes the word backwards*/
//Prints all permutations
cout << endl << reverse << " ";
for (i = 0; i < word.length() - 1; i++)
{
for (j = 0; j < word.length(); j++)
{
randCH = word.substr(rand() % length, 1);
cout << randCH;
}
cout << " ";
cout << endl;
you can use std::next_permutation which is already built to achieve this:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string word;
cin >> word;
sort(word.begin(),word.end());
do {
cout << word <<endl;
} while(next_permutation(word.begin(),word.end()));
}
This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 8 years ago.
I have a weird problem, so my instructor told us to create a simple program using vectors that will first ask the user how many integers they want to enter, and after the numbers were entered via a space as a delimiter the output should add 2 to each vector element.
Ex -
How many numbers are you going to enter = 4 (Lets assume the user enters 4)
Enter the numbers = 11 45 71 24 (Lets assume the user entered these 4 numbers)
THE OUTPUT SHOULD BE THIS = 13 47 73 26 (with spaces added 2)
Since using vectors is a must, i know how to add add 2 with a normal integer vector output but when it comes with spaces i have no idea, so far the program i wrote will accept everything before the space into the vector and will add 2 to it.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector <int> userInput;
int input;
int number;
int num1;
cout << "How many numbers are you going to enter ? :";
cin >> number;
cout << "Enter the Numbers : " << endl;
cin >> input;
userInput.push_back(input);
cout << "Vector Contains : ";
for (unsigned int i = 0; i < userInput.size(); i++)
{
cout << userInput[i] + 2;
}
system("pause>nul");
return 0;
}
The reason you're only taking in one input is because you're only taking in one int from std::cin. The other ints are still remaining in the stream. You should do this:
while(/*we still have stuff to extract*/)
{
std::cin >> input;
userInput.push_back(input);
}
However, we still need to know when to stop. Since we're only expecting one line of input from the user, we can do std::cin.peek() != '\n' to check if we've reached the point where the user pressed the Enter key earlier.
Thank you for reading.
The standard extraction operator for int expects whitespace as the separator between items so you don't need to do anything special there. Just read ints, put them in your vector, do the addition, and print out the results. Assuming you've already read n for the count, the real work could look something like this:
std::copy_n (std::istream_iterator<int>(std::cin),
n,
std::back_inserter(your_vector));
std::transform(your_vector.begin(), your_vector.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int i){ return i + 2; });
Try the following
#include <iostream>
#include <vector>
#include <cstdlib>
int main()
{
std::cout << "How many numbers are you going to enter ? :";
size_t n = 0;
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " numbers : " << std::endl;
int x;
for ( size_t i = 0; i < n && std::cin >> x; i++ ) v[i] = x;
for ( int x : v ) std::cout << x + 2 << ' ';
std::cout << std::endl;
std::system( "pause>nul" );
return 0;
}
If to input
4
11 45 71 24
the output will be
13 47 73 26
Other approach is to use standard function std::getline and std::istringstream instead of the operator >>
For example
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <sstream>
#include <limits>
int main()
{
std::cout << "How many numbers are you going to enter ? :";
size_t n = 0;
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " numbers : " << std::endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
std::string s;
std::getline( std::cin, s );
std::istringstream is( s );
int x;
for ( size_t i = 0; i < n && is >> x; i++ ) v[i] = x;
for ( int x : v ) std::cout << x + 2 << ' ';
std::cout << std::endl;
std::system( "pause>nul" );
return 0;
}
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