Finding out if a string is part of an array conditionally - c++

This is a basic c++ console application that I am working on, just to test things out before o do something a little bit more advanced. I would like to know how I would find out if the user input is part of my String array with an if statement here is the code so far...
#include <iostream>
#include <string>
using namespace std;
int main(){
string array[] = {"1","2","3"};
for(;;){
cout << "Enter a random number";
int randNum = 0;
cin >> randNum;
if(/* randNum is part of the array */)
{
//do something
}
else{
//do something
}
}
return 0;
}

First off, you clearly want to check your input after reading:
if (cin >> randNum) {
...
}
Next, I think you would want to align the types, i.e., if you read an int you probably want to have your array also to contain ints:
int array[] = { 1, 2, 3 };
If these are given you can just check like so:
if (std::end(array) != std::find(std::begin(array), std::end(array), randNum)){
...
}
(if you don't use C++ 2011, you need some other way to get the begin and end iterator your array but there are plenty ways, including defining templates begin() and end() as needed).
If you really want to check the int against an array of std::strings, you'd need a predicate which checks the int against a std::string.

You can utilize std::find for this, however, you'll need to convert randNum to a string first -
std::stringstream ss;
ss << randNum;
std::string to_check = ss.str();
if(std::find(array, array + 3, to_check) != (array + 3)) {
//Logic
} else {
//
}

Related

how to insert space separated input into an array in C++ [duplicate]

A String is given as an input which consists of numbers and I want to convert it into integer arrays in C++.
#include <string>
#include <iostream>
#include <sstream>
using std::string;
using std::stringstream;
using std::cout;
using std::endl;
int main(int argc,char** argv) {
string num="-24 2 90 24 50 76";
stringstream stream(num);
while(stream){
int n;
stream>>n;
cout<<n<<endl;
}
return 0;
}
Output(GCC) :
-24 2 90 24 50 76 76
Why am i getting extra value and what is the efficient to convert them into integer array ?
UPDATE:
What if the string stream contains delimiter other than space, How to parse this?
For eg:
string num="-24,2,90,24,50,76";
The end of file condition is not set upon a succesful parse, you have to check the state of the stream after parsing.
The second 76 is basically just pure chance. An unsuccesful parse leaves the target operand untouched, and because you did not initialize n, it can be anything.
A quickfix:
stream>>n;
if (stream)
cout<<n<<endl;
A cleaner fix:
int n;
while(stream >> n){
cout<<n<<endl;
}
To store those integers, the canonical way is to use std::vector if the number of elements is unknown. An example usage:
std::vector<int> values;
int n;
while(stream >> n){
...do something with n...
values.push_back(n);
}
However, you can use iterators over streams and use the following:
// Use std::vector's range constructor
std::vector<int> values(
(std::istream_iterator<int>(stream)), // begin
(std::istream_iterator<int>())); // end
Another means of dealing with a character separated integers list using a vector, which is even perhaps a little more simplistic is more like this:
string str = "50,2,25,38,9,16";
vector<int> ints;
stringstream ss(str);
int n;
char ch;
while(ss >> n) {
if(ss >> ch)
ints.push_back(n);
else
ints.push_back(n);
}
that way you can move past any character separations (if they exist) first and then default back to grabbing the integers and adding them to the list if they don't (AKA the end of the list)
i don't know if you find the answer for your updated question or not. if you don't you can easily do it by the code
for (string::iterator it = num.begin(); it != num.end(); ++it) {
if (*it == ',') {
*it = ' ';
}
else continue;
}
this code removes all your colons and replaces them by space. then you can do just normally

Expected Primary-Expression before ']' token?

I'm trying to be able to call a function with the vector and for some reason it's saying "expected primary expression before ']'. The vector could hold any number of files, depending on the amount of numbers in myfile, so I'm not sure what I should put there.
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
using namespace std; // not recommended
double averageCalc(string[],int);
int main () {
double average;
string line;
ifstream myfile ("array_pgmdata.txt");
//int index = 0; // not needed
//string myArray[index]; // UB - if it even compiles, it's a VLA of size 0.
std::vector<std::string> myArray; // use this instead to be able to grow it
// dynamically
if (myfile) // open and in a good state
{
// while (! myfile.eof() ) // It'll not be eof when you've read the last line
// only when you try to read beynd the last line,
// so you'll add "line" one extra time at the end
// if you use that. Use this instead:
while(getline(myfile, line))
{
// myArray[index++] << line; // you have 0 elements in the array and
// can't add to it in any way
myArray.push_back(line);
}
}
else cout << "Unable to open file";
for(size_t idx=0; idx < myArray.size(); ++idx) {
std::cout << myArray[idx] << "\n";
}
average = averageCalc(myArray[], line); // error here
return 0;
}
double averageCalc(string nums[], int count)
{
int a, total, elements, averaged1, averaged2;
// string averaged2;
for(a = 0; a < count; a++)
{
total+=a;
elements++;
}
averaged1 = total / elements;
return averaged2;
}
There's a few problems here. Firstly, your function averageCalc expects a parameter of type string[] which is an array of strings. When you call the function, you are trying to pass it a std::vector<string>, which is not an array of strings, it is a class. Presumably, you would want to change your function to take in a vector, like so:
double averageCalc( const std::vector<string> & nums ); // no need for size now
The other issue you have is in calling your function. When you call it, you pass myArray[] as a parameter, which is the error you compiler is giving you. This is not valid syntax, you simply want to pass in myArray.
I think that the error occurs becase firstly you create the array with std::vector<std::string> myArray; so the data is string type but when you want to calculate the average value the function expects a value int, double etc. in order to perform math. Either change the string to int or use a function to convert it:
int main()
{
string s = "12345";
// object from the class stringstream
stringstream geek(s);
// The object has the value 12345 and stream
// it to the integer x
int x = 0;
geek >> x;
// Now the variable x holds the value 12345
cout << "Value of x : " << x;
return 0;
}

Scanning User Input for Strings Declared in an Array

I am creating a program that scans user input for words that are listed in an array. The find() function seems like it'll work, but I can't find anything showing how to implement it for what I want to do. I'm pretty new to programming (obviously).
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
string subj [5]={"I","He","She","We","They"};
string verb [5]={" like"," hate"," sacrifice"," smell"," eat"};
string obj [5]={" bacon","s cats","s bagels","s children","s cops"};
string greeting [5]={"How are you","How's it going","Sup dude","Hey","Hello"};
string negvibe [4]={"bad","terrible","lousy","meh"};
string userfeeling;
int main()
{
srand(time(0));
int rando = rand() %5;//generates a random number between 0 and 4
int rando1 = rand() %5;
int rando2 = rand() %5;
cout << greeting [rando1] << "." << endl;
getline(std::cin,userfeeling);
if .... // What has to be done here?
find(negvibe, negvibe + 4, userfeeling) != negvibe + 4);
// Something like that?
// then ...
{
cout << subj[rando] << verb[rando1] << obj[rando2] <<"." <<endl;
}
return 0;
}
To make find work properly you should user iterators like so
if(find(std::begin(negvibe), std::end(negvibe), userfeeling) != std::end(negvibe)){
//code you want to happen if your word is found
}
Also in your current code, the if statement doesnt actually do anything since you end it with a semicolon and not {} or leave it blank if its one line. You can see an example of the if statement as well
Below is a link to find and iterators
http://www.cplusplus.com/reference/algorithm/find/
That find function will find some element of the negvibe array that is equal to userfeeling. If you are checking whether any element of negvibe is a substring of userfeeling, you should loop through negvibe and use the std::string::find method.
bool found_negvibe = false;
for (int i = 0; i < sizeof(negvibe) / sizeof(*negvibe); i++) {
found_negvibe = found_negvibe || userfeeling.find(negvibe[i]) != string::npos;
}
Also, you don't need to specify the size of the negvibe array, you can write this:
string negvibe[] = {"bad","terrible","lousy","meh"};
One more thing, you might prefer to use a std::vector over an array, if only because c++'s faculties for getting the size of a vector are slightly more succinct than those for getting the size of an array.
vector negvibe = {"bad","terrible","lousy","meh"};
bool found_negvibe = false;
for (int i = 0; i < negvibe.size(); i++) {
found_negvibe = found_negvibe || userfeeling.find(negvibe[i]) != string::npos;
}

Count matches in an array

I can't figure out how to do this.
The question: Implement the function
int count_matches(const string arr[], int size, string query);
Return the number of strings in the array that are equal to query or
-1 if size if less than 0.
My answer:
#include <iostream>
#include <cmath>
#include<string>
using namespace std;
int count_matches(const string arr[], int size, string query){
int i = 0;
int numMatches;
for (;i<size;i++) {
if (string[i] == (string[i]+1)){
numMatches++;
}
}
return numMatches;
}
int main(){
string selection;
const string array[4]={"dog", "cat", "dog", "dog"};
cout<<"which animal do you want?"<<endl;
cin>> selection;
cout<< "there are " << count_matches(array, 4, selection)<< " matches"<<endl;
return 0;
}
What is wrong?
int count_matches(const string arr[], int size, string query){
int numMatches(0);
for (int i=0; i<size; ++i)
{
if (arr[i] == string)
{
++numMatches;
}
}
return numMatches;
}
This should be a solution to your problem but you will never learn anything from gaining the answer this way. I'd advise reading this tutorial on arrays and loops to better understand how to tackle the problem next time.
Once you get your code to compile, you need to look carefully at this block:
if (string[i] == (string[i]+1)) {
numMatches++;
}
What do you actually want to compare here? string is a type. Take another look at the arguments that you pass into the function and that should make it clear.
Then, once you have a match, you increment numMatches. But what value does this have to start with? What value should it have to start with?
Note that std::count() does exactly what your count_matches() function should do:
std::count(array, array + 4, selection)
This will probably not statisfy whomever marks your homework, but it is worth playing with and learning if you want to advance your C++ skills.
Good luck!

How do I convert a string in C++ or C to an integer array?

How do I convert a string into an array of integers? Can I use sstream, because atoi doesn't work?!
As you said in the comments, you got a binary string and you want to convert it into integers. Use bitset for that:
std::istringstream is(str);
std::bitset<32> bits; // assuming each num is 32 bits long
while(is >> bits) {
unsigned long number = bits.to_ulong();
// now, do whatever you want with that long.
v.push_back(number);
}
If you only have one binary number in that string str, you can get away with
unsigned long number = std::bitset<32>(str).to_ulong();
Converting that in C is also possible...
long value;
char const *c = str;
for(;;) {
char * endp;
value = strtol(c, &endp, 2);
if(endp == c)
break;
/* huh, no vector in C. You gotta print it out maybe */
printf("%d\n", value);
c = endp;
}
atoi can't parse binary numbers. But strtol can parse them if you tell it the right base.
How exactly would you like the conversion to work?
Do you simply want an array containing the ASCII value of each character in the array? (so "abc" becomes [97, 98, 99, 0])?
Or do you want to parse the string somehow? ("1, 2, 3" becomes an array [1, 2, 3])
In the first case, in C++, I'd do something like this:
struct convert {
int operator()(char c) {
return static_cast<int>(c);
}
};
std::string str = "hello world";
std::vector<int> result;
std::transform(str.begin(), str.end(), std::back_inserter(result), convert())
Of course you could use a raw array instead of the vector, but since the length of the string is probably going to be variable, and then arrays are just asking for trouble.
If this wasn't what you wanted, you might want to edit your question to be more specific.
From what I understand, for input string "110013" would be converted to array {1,1,0,0,1,3}. Here is how to do it in C++:
string a = "1110011000";
vector<int> v;
for(int i = 0 ; i < a.length() ; i++){
v.push_back(a[i] -'0');
}
// Check the result
for(int i = 0 ; i < v.size() ; i++){
cout << v[i] << endl;
}
Quick string splitter routine:
convert(string str, string delim, vector<int>& results)
{
int next;
char buf[20];
while( (next= str.find_first_of(delim)) != str.npos ) {
if (next> 0)
results.push_back(atoi(str.substr(0,next), buf, 10));
str = str.substr(next+1);
}
if(str.length() > 0)
results.push_back(atoi(str.substr(0,next), buf, 10));
}
You can use stringstream instead of atoi (which does work, on a single int at a time)
int i;
stringstream s (input_string)
s >> i;
If you combine my and jalf's code, you'll get something really good.
Use the istream_iterator in conjunction with a string stream.
By Array I am assuming you really mean a std::vector as you don't know the number of integers at compile time. But the code can easily be modified to use an array rather than a vector.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::string data = "5 6 7 8 9";
std::vector<int> store;
std::stringstream dataStream(data);
std::copy(std::istream_iterator<int>(dataStream),
std::istream_iterator<int>(),
std::back_inserter(store)
);
// This line just copies the store to the std::cout
// To verify it worked.
std::copy(store.begin(),
store.end(),
std::ostream_iterator<int>(std::cout,",")
);
}
Language: C
Header:
#include <stdlib.h>
Function Prototype:
long int strtol(const char *nptr, char **endptr, int base);
Example Usage:
strtol(nptr, (char **) NULL, 10);