How do I create a check for this code? - c++

I'm trying to make it so that the code checks if the user input is between (and including) 10 and 100.
Being so used to just single inputs, I'm having trouble since it's an array...
int main()
{
int numlist[20];
for(int i = 0; i < 20; i++)
{
cout << "Enter # " << i + 1 << " : ";
// here is where I am going wrong...
if ((numlist[i] <= 100) && (numlist[i] >= 10))
{
cin >> numlist[i];
}
}
}

Shouldn't you put the input statement cin >> numlist[i] before the test if ((numlist[i] <= 100) && (numlist[i] >= 10)) ?

it looks like you want to do something like this:
int temp = 0;
for (int i = 0; i < 20; i++)
{
cin >> temp;
if ((temp <= 100) && (temp >= 10))
numlist[i] = temp;
}

Just to give a slightly different way you could do this, you might consider a vector instead of an array, and read the data with an istream_iterator along with a standard algorithm:
std::vector<int> numlist;
std::remove_copy_if(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(numlist),
[](int i)->bool { return i<10 || i > 100; });
Edit: I guess since I'm using C++11 lambda, I could also use the C++11 copy_if, which expresses the intent a bit more directly:
std::copy_if(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(numlist),
[](int i)->bool { return i>=10 && i<=100; });
As far as "clever" goes, that's not the intent at all -- rather, what's desired is a simple, direct expression of the original intent: to copy (filtered) data from standard input to a container. It does take a bit to get used to the idea of treating files as containers (especially ones like std::cin, which is normally interactive), but ultimately a file is a sequence, and istream_iterator/ostream_iterator just let you treat them like other sequences.

As others have noted, you can't check a value that you haven't even read (from the user).
To constraint the input you must check the input after cin inside a do while loop, as long as it doesn't satisfy the constraint.
do
{
//you might cout here
cin >> numlist[i];
}
while ((numlist[i] > 100) || (numlist[i] < 10));

Related

Unıque Random Number Check form Array c++

#include <iostream>
#include<ctime>
#include<cstdlib>
#include<string>
#include<cmath>
using namespace std;
int main()
{
bool cont = false;
string str;
int num, num2;
cin >> str >> num;
int arr[10];
int a = pow(10, num);
int b = pow(10, (num - 1));
srand(static_cast<int>(time(NULL)));
do {
num2 = rand() % (a - b) + b;
int r;
int i = 0;
int cpy = num2;
while (cpy != 0) {
r = cpy % 10;
arr[i] = r;
i++;
cpy = cpy / 10;
}
for (int m = 0; m < num; m++)
{
for (int j = 0; j < m; j++) {
if (m != j) {
if (arr[m] == arr[j]) {
break;
}
else {
cont = true;
}
}
}
}
cout << num2 << endl;
} while (!cont);
return 0;
}
I want to take a number from the user and produce such a random number.
For example, if the user entered 8, an 8-digit random number.This number must be unique, so each number must be different from each other,for example:
user enter 5
random number=11225(invalid so take new number)
random number =12345(valid so output)
To do this, I divided the number into its digits and threw it into the array and checked whether it was unique. The Program takes random numbers from the user and throws them into the array.It's all right until this part.But my function to check if this number is unique using the for loop does not work.
Because you need your digits to be unique, it's easier to guarantee the uniqueness up front and then mix it around. The problem-solving principle at play here is to start where you are the most constrained. For you, it's repeating digits, so we ensure that will never happen. It's a lot easier than verifying if we did or not.
This code example will print the unique number to the screen. If you need to actually store it in an int, then there's extra work to be done.
#include <algorithm>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>
int main() {
std::vector<int> digits(10);
std::iota(digits.begin(), digits.end(), 0);
std::shuffle(digits.begin(), digits.end(), std::mt19937(std::random_device{}()));
int x;
std::cout << "Number: ";
std::cin >> x;
for (auto it = digits.begin(); it != digits.begin() + x; ++it) {
std::cout << *it;
}
std::cout << '\n';
}
A few sample runs:
Number: 7
6253079
Number: 3
893
Number: 6
170352
The vector digits holds the digits 0-9, each only appearing once. I then shuffle them around. And based on the number that's input by the user, I then print the first x single digits.
The one downside to this code is that it's possible for 0 to be the first digit, and that may or may not fit in with your rules. If it doesn't, you'd be restricted to a 9-digit number, and the starting value in std::iota would be 1.
First I'm going to recommend you make better choices in naming your variables. You do this:
bool cont = false;
string str;
int num, num2;
cin >> str >> num;
What are num and num2? Give them better names. Why are you cin >> str? I can't even see how you're using it later. But I presume that num is the number of digits you want.
It's also not at all clear what you're using a and b for. Now, I presume this next bit of code is an attempt to create a number. If you're going to blindly try and then when done, see if it's okay, why are you making this so complicated. Instead of this:
num2 = rand() % (a - b) + b;
int r;
int i = 0;
int cpy = num2;
while (cpy != 0) {
r = cpy % 10;
arr[i] = r;
i++;
cpy = cpy / 10;
}
You can do this:
for(int index = 0; index < numberOfDesiredDigits; ++index) {
arr[index] = rand() % 10;
}
I'm not sure why you went for so much more complicated.
I think this is your code where you validate:
// So you iterate the entire array
for (int m = 0; m < num; m++)
{
// And then you check all the values less than the current spot.
for (int j = 0; j < m; j++) {
// This if not needed as j is always less than m.
if (m != j) {
// This if-else is flawed
if (arr[m] == arr[j]) {
break;
}
else {
cont = true;
}
}
}
}
You're trying to make sure you have no duplicates. You're setting cont == true if the first and second digit are different, and you're breaking as soon as you find a dup. I think you need to rethink that.
bool areAllUnique = true;
for (int m = 1; allAreUnique && m < num; m++) {
for (int j = 0; allAreUnique && j < m; ++j) {
allAreUnique = arr[m] != arr[j];
}
}
As soon as we encounter a duplicate, allAreUnique becomes false and we break out of both for-loops.
Then you can check it.
Note that I also start the first loop at 1 instead of 0. There's no reason to start the outer loop at 0, because then the inner loop becomes a no-op.
A better way is to keep a set of valid digits -- initialized with 1 to 10. Then grab a random number within the size of the set and grabbing the n'th digit from the set and remove it from the set. You'll get a valid result the first time.

Extraction operator causing my program to exit?

I'm a usual lurker but this is my first post! I understand you guys like detail so I will do my best. I will appreciate whatever input anyone has.
I am working on an overloading the extraction operator for an object with a dynamic array of digits. The console input will have leading white space, then an int, then anything after. I need to ignore white space, extract the int, and then leave the rest alone. Easy right?
Here is an example of code I found online:
istream & operator >> (istream &m, MyInt & p)
{
int x = 0;
p.currentLength = 0;
while ((m.peek() == '\n') || (m.peek() == '\0') ||
(m.peek() == '\t') || (m.peek() == ' '))
{
m.get();
}
while ((m.peek() >= '0') && (m.peek() <= '9'))
{
if (p.currentLength >= p.maxSize)
{
p.grow();
}
m >> p.theNumber[x];
x++;
p.currentLength++;
}
m.get();
// reverse the order (i.e. - 123 to 321)
char * temp = new char[p.maxSize];
for (int y = 0; y < p.currentLength; y++)
{
temp[y] = p.theNumber[p.currentLength - 1 - y];
}
delete [] p.theNumber;
p.theNumber = temp;
return m;
}
Now, I understand this method may work, however to me, that seems like an extremmeelly inefficient method. For a trillion digit number, Grow() would reallocate the array a trillion times! Perhaps this is not as bad as I think it is?
My current method has been using seekg() and peek() and get(). Like so:
istream& operator >> (istream& is, MyInt& z)
{
int i = 0, j = 0;
// check if next char is white
while (is.peek() == 38)
{
j++;
is.seekg(j); // skip if white
}
while (isdigit(is.peek()))
{
i++;
is.seekg(j + i);
if (!is.peek())
{
is.clear();
break;
}
}
is.seekg(j);
z.length = i;
z.digits = new int[i + 1];
for (i = 0; i < z.length; i++)
{
z.digits[i] = C2I(is.get());
}
return is;
}
Also, here is my main:
int main()
{
MyInt B;
cout << "\n\nChange B to what num? ---> ";
cin >> B;
cout << "B is now: " << B;
char c;
cout << "\n\n\n\n\nEnter char to exit : ";
cin >> c;
return 0;
}
For the life of me I can not find what is causing my program to exit. The last output seems to say, 'B is now: -1'
I believe the this means the << B failed. I have B initialized to 0 currently, and the rest of my code has presented no other issues. It's private member data only include the pointer and a length (num of digits). Also C2I() is a function that converts '0' through '9' to 0 through 9.
A big issue for me is I am fairly new to parsing, so I don't have very eloquent ways to test this, or other ideas.
Again I appreciate everything you guys do. I have already learned a great deal from browsing here!

Custom Implementation of strcmp in C++ not Working

I am scratching my head... why is the return statement inside strcmp_iter never being called?
When I run this function, the output is simply to count from 0 to 6 and then terminate... no return statement. Very frustrating. Interestingly, if I change myString2 to "abcdefG" then everything works fine... very odd.
int strcmp_iter(string s1, string s2) {
int i = 0;
for (; ((s1.at(i) == s2.at(i)) && (i <= s1.length())); i++) {
cout << i << endl;
}
return s1.at(i) - s2.at(i);
}
int main() {
string myString1 = "abcdefg";
string myString2 = "abcdefg";
int count_iter = strcmp_iter(myString1, myString2);
cout << "Iter: " << count_iter << endl;
return 0;
}
You are looping beyond the bounds of the string and probably throwing an std::out_of_range exception. Change your condition to
i < s1.length()
and make that check before any calls to std::string::at(size_type pos)
Also, beware your function can only work if s2 is at least as long as s1. You should probably be looping up to one less than std::min(s1.length(), s2.length()).
Whenever I see this construction, it makes me cringe:
for (; ((s1.at(i) == s2.at(i)) && (i <= s1.length())); i++)
C-like languages always do short circuit evaluation and from left to right. So the condition for termination—and validating that the comparison makes sense to do—should precede the comparison:
int n = s1.length();
if (s2.length() < n)
n = s2.length(); // choose smaller length
for (; i < n && s1.at(i) == s2.at(i); i++)
(I have also removed unnecessary parentheses, limited the search length to the short string, and changed <= to < because of how array subscripts work.)
for (; ((s1.at(i) == s2.at(i)) && (i <= s1.length())); i++) {
use i < s1.length()

C++ best practice to identify whether a digit is in a certain range

Which way is better to identify a digit? I'm analyzing a 9 digit array of integers to test whether they are all between 0-9 inclusive.
for (i = 0; i < 9; i++) {
if (str[i] < 48 || str[i] > 57) {
cout >> "failed" >> endl;
}
else {
cout >> "passed" >> endl;
}
}
for (i = 0; i < 9; i++) {
if (str[i] < '0' || str[i] > '9') {
cout >> "failed" >> endl;
}
else {
cout >> "passed" >> endl;
}
}
You can just use isdigit.
Your second option also works. The first one doesn't have to, because '0' doesn't necessarily have to correspond to 48. The values are guaranteed to be consecutive, but they don't have to start at 48 (although they likely do).
I would use std::all_of in combination with a predicate (better if a short, terse lambda) that uses std::isdigit():
bool ok = std::all_of(begin(str), end(str), [] (char c) { return std::isdigit(c); });
This allows you to test any sub-range you wish, and the iteration cycle comes for free.
You have to include the <cctype> header (for std::isdigit()) and the <algorithm> header (for std::all_of).
EDIT:
If you do not want to use a lambda, you can even pass in the std::digit function directly, if you provide a proper cast (see this Q&A for an explanation):
bool ok = std::all_of(begin(str), end(str), (int (*)(int))std::isdigit);
The cast is necessary because in the std namespace, there are overloads of isdigit which is causing problem in overload resolution. The other topic discusses a similar case in a bit detail.
Or if that looks cumbersome, you can do this instead:
int (*predicate)(int) = std::isdigit;
bool ok = std::all_of(begin(str), end(str), predicate);
That should work fine!

Return all prime number before a given number(Homework C++)

I'm not trying to ask you guys to help me to do homework because i've do much research and also try to program it myself but still i encounter problem and i think so far i've know where the problem is but still no solution can be figure out by me :
The Code
#include <iostream>
#include <string>
#include <cmath>
int main(void)
{
using namespace std;
int num;
int max;
string answer = "";
cin >> num;
for(int i = 2 ; i < num ; i++)
{
max = sqrt(i);
if(max < 2) // This must be done beacuse sqrt(2) and sqrt(3)
{ // is 1 which will make it become nonprime.
answer += i;
answer += ' ';
continue;
}
for(int j = 2 ; j <= max ; j++) // Trial division ,divide each by integer
{ // more than 1 and less than sqrt(oftheinteger)
if(i % j == 0)
break;
else if(j == max)
{
answer += i + " ";
answer += ' ';
}
}
}
cout <<"The answer is " << answer ;
return 0;
}
The Question
1.)This program will prompt for a number from user and return all the prime number before it(e.g if user input 9 : then the answer is 2 , 3 , 5 , 7).
2.)I think the wrong part is the string and integer concatenation , till now i still puzzle how to concat string and integer in C++(Previous Javascript programmer so i'm accustomed to using + as string-int concat operator)
3.)Beside the problem i mention above , so far i've go through the code and find none of other problem exist.If any expert manage to find any , mind to point it out to enlighten me??
4.)If there's any mistake in terms of coding or algorithm or anything done by me , please don't hesitate to point it out , i'm willing to learn.
Thanks for spending time reading my question
The usual way to perform formatting in C++ is to use streams.
In this situation, you can use a std::stringstream to accumulate the results, and then convert it into a string when you do the final printing.
Include sstream to get the required type and function declarations:
#include <sstream>
Declare answer to be a std::stringstream instead of a std::string:
stringstream answer;
and then wherever you have:
answer += bla;
, replace it with:
answer << bla;
To get a std::string out of answer, use answer.str():
cout << "The answer is " << answer.str();
If you have to store your complete output before printing it out (I would probably print it as I go, but up to you), a simple way is to use stringstreams.
In this case, rather than answer being an std::string, we can change it to an std::stringstream (and include the <sstream> header).
Now rather than having:
answer += i;
We can just make a simple change and have:
answer << i;
Just as you would if you were printing to cout (which is an ostream).
So basically, += in your code would become <<.
Similar to printing to cout, you can also chain together such as:
answer << a << b
Now to print your stringstream to cout, all you'd need to do is:
cout << my_stringstream.str()
See how you go. I don't want to provide you with the complete since it's homework.
You can go around the string concatenation problem if you just print what you have so far:
int main()
{
int num;
int max;
string answer = "";
cin >> num;
cout << "The answer is ";
for(int i = 2 ; i < num ; i++)
{
max = sqrt((double)i);
if(max < 2) // This must be done beacuse sqrt(2) and sqrt(3)
{ // is 1 which will make it become nonprime.
cout << i << ' ';
continue;
}
for(int j = 2 ; j <= max ; j++) // Trial division ,divide each by integer
{ // more than 1 and less than sqrt(oftheinteger)
if(i % j == 0)
break;
else if(j == max)
{
cout << i << ' ';
}
}
}
return 0;
}
As other mentioned one way to do concatenation is std::stringstream.
it's not very beautiful, but it works. I use a general library "genlib.h", I'm not sure what you use, so you might need to replace that or I can send it to you.
#include "genlib.h"
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
bool IsPrime(int num);
int main()
{
int num;
int i = 2;
cout << "Enter an integer to print previous primes up to: ";
cin >> num;
cout << endl << "The primes numbers are: " << endl;
while(i < num){
if (IsPrime(i) == true){
cout << i << ", ";
}
i++;
}
return 0;
}
bool IsPrime(int num){
if((num == 2) || (num == 3)) {
return true;
}else if ((num % 2) == 0){
return false;
}else{
for (int i = 3; i < sqrt(double(num))+1; i++){
if ((num % i) == 0){
return false;
}
return true;
}
}
}
you need tn convert the integer to string (char*, exactly) using :
answer += itoa(i);
or using standard function :
char str[10];
sprintf(str,"%d",i);
answer += str;
and if you want to avoid using sqrt function, you can replace :
for(int i = 2 ; i < num ; i++)
{
max = sqrt(i);
with :
for(int i = 2 ; i*i < num ; i++)
{
The problem is that the + operator of std::string accepts strings as parameter, pointers to an array of chars, or single chars.
When a single char is used in the + operator, then a single char is added to the end of the string.
Your C++ compiler converts the integer to char before passing it to the operator + (both char and int are signed integer values, with different bit number), and therefore your string should contain a strange char instead of the numbers.
You should explicitly convert the integer to string before adding it to the string, as suggested in other answers, or just output everything to std::cout (its operator << accepts also int as parameter and convert them correctly to string).
As a side note, you should receive a warning from the C++ compiler that your integer i has been converted to char when you add it to the string (the integer has been converted to a lower resolution or something like that). This is why is always good to set the warning level to high and try to produce applications that don't generate any warning during the compilation.
You could perform a faster lookup by storing your known prime numbers in a set. These two sample functions should do the trick:
#include <iostream>
#include <set>
#include <sstream>
#include <string>
typedef std::set< unsigned int > PrimeNumbers;
bool isComposite(unsigned int n, const PrimeNumbers& knownPrimeNumbers)
{
PrimeNumbers::const_iterator itEnd = knownPrimeNumbers.end();
for (PrimeNumbers::const_iterator it = knownPrimeNumbers.begin();
it != itEnd; ++it)
{
if (n % *it == 0)
return true;
}
return false;
}
void findPrimeNumbers(unsigned int n, PrimeNumbers& primeNumbers)
{
for (unsigned int i = 2; i <= n; ++i)
{
if (!isComposite(i, primeNumbers))
primeNumbers.insert(i);
}
}
You could then invoke findPrimeNumbers like so:
unsigned int n;
std::cout << "n? ";
std::cin >> n;
PrimeNumbers primeNumbers;
findPrimeNumbers(n, primeNumbers);
And if you really need to dump the result in a string:
std::stringstream stringStream;
int i = 0;
PrimeNumbers::const_iterator itEnd = primeNumbers.end();
for (PrimeNumbers::const_iterator it = primeNumbers.begin();
it != itEnd; ++it, ++i)
{
stringStream << *it;
if (i < primeNumbers.size() - 1)
stringStream << ", ";
}
std::cout << stringStream.str() << std::endl;
Since you're willing to learn, you can perform both join and split algorithm on string/sequence by using Boost String Algorithms Library.
This solution is not perfect, but it's basic C++ usage (simple containers, no structure, only one typedef, ...).
Feel free to compare your results with The First 1000 Primes.
Good luck