Determine if a character exists within a string? (Not using loops) - c++

I'm trying to create a funcion that returns true if a non-alphanumeric character exists within a string. I cannot use a loop, however, and I'm looking for the right algorithm to do so.
not_alphanumeric("hello") // This would return FALSE
not_alphanumeric("h%llo") // This would return TRUE
I need to know what type of algorithm I need to use in order to do this, OR if there is some non-loop related method in order to do this.

If you don't know about the any_of() defined in algorithm library, you should take a look into it if you're making a program which contains no loops.
Consider this:
#include <iostream>
#include <algorithm>
bool checkAlphaNum(char *);
int main(void) {
char *string = new char[1024];
std::cout << "Enter a string: ";
std::cin >> string;
std::cout << checkAlphaNum(string) << std::endl;
return 0;
}
bool checkAlphaNum(char *arr) {
// verifying each character of the given string argument
return std::any_of(arr, arr + strlen(arr), [](char ch)
{return isalnum(ch);});
}

Related

Check if a string exists in array

For a school assignment I need to check whether a string entered by the user is stored in a pre-defined word array.
I want to implement a function to perform the check, that may look like this:
bool exists(dict words, char check) { /* how to implement this? */ }
But I have no clue whether this will work or how to implement it. Can anyone help?
Here's my code:
#include <iostream>
#include <string>
using namespace std;
struct dict {
string word;
};
int main() {
dict words[5];
words[0].word = 'abc';
words[1].word = 'bcd';
words[2].word = 'cde';
words[3].word = 'def';
words[4].word = 'efg';
char user_input[100];
cin.getline(user_input, 100);
if (...) { // how do I check if the user input is in my word array?
cout << "found\n";
}
else {
cout << "not found\n";
}
}
First of all, dict is a structure and char is type able to hold single character, so you would rather need to have:
bool exists(const dict* words, const string& check);
From this point, I would say, that:
const dict* should be changed to const vector<dict>&.
std::getline is able to read input directly into string, so no plain char array is needed.
But since it's a school assignment, I suppose, that you have some limitations (and can't use neither std::vector nor std::find, that would do the job). So:
bool exists(const dict* words, size_t count, const std::string& check)
{
for(size_t n = 0; words && (n < count); ++n)
{
if(words[n].word == check)
return true;
}
return false;
}
Example:
dict langs[3];
langs[0].word = "C++";
langs[1].word = "Java";
langs[2].word = "Python";
std::string s_1 = "Java";
std::string s_2 = "C++ 11";
printf("exists(%s) : %s\n", s_1.c_str(), exists(langs, 3, s_1) ? "yes" : "no");
printf("exists(%s) : %s\n", s_2.c_str(), exists(langs, 3, s_2) ? "yes" : "no");
Output:
exists(Java) : yes
exists(C++ 11) : no
Link to sample code.
As the other answer has already pointed out, you should add a size parameter to the function signature in order to be able to iterate the array (especially to know when to stop iteration.). Then a simple loop with a comparison will do the trick.
Note that you shouldn't normally need to use raw arrays in C++, but rather one of the containers from the standard library, e.g., std::vector. Also, you should use std::string and std::getline() for your user input, and you should fix your string literals (use double quotes "..." instead of single quotes '...'). Further, you should avoid using namespace std; conciouslessly. Have a look at the links at the end of this post for some further reading on these points.
Example code:
#include <iostream>
#include <string>
#include <vector>
bool exists(std::string const & user_input,
std::vector<std::string> const & words)
{
for (int i = 0; i < words.size(); i++)
if (user_input == words[i])
return true;
return false;
}
int main() {
std::vector<std::string> words(5);
words[0] = "abc";
words[1] = "bcd";
words[2] = "cde";
words[3] = "def";
words[4] = "efg";
std::string user_input;
std::getline(std::cin, user_input);
if (exists(user_input, words))
std::cout << "found\n";
else
std::cout << "not found\n";
}
Example output:
$ g++ test.cc && echo "abc" | ./a.out
found
The following might be beyond the scope of your school assignment, but maybe this will be helpful for future visitors to this question.
Note that an array (which std::vector is) is not the most efficient data structure to perform this sort of task, as you have to iterate the entire array to check every single item (linear complexity).
The C++ standard library also provides the container types std::set and std::unordered_set (the latter since C++11). Here the search space is organized in a special way (binary search tree: logarithmic complexity, hash table: constant complexity on average) to improve lookup time of the key type (std::string in this case).
Here's an example:
#include <iostream>
#include <string>
#include <set>
typedef std::set<std::string> set_type;
bool input_exists(std::string input, set_type const & words) {
return words.find(input) != words.end();
}
int main() {
set_type words = {"abc", "bcd", "cde", "def", "efg"};
std::string input;
if (std::getline(std::cin, input)) {
std::cout << "input: '" << input << "' ";
if (input_exists(input, words))
std::cout << "found\n";
else
std::cout << "not found\n";
}
}
Example output:
$ g++ test.cc -std=c++11
$ echo "abc" | ./a.out
input: 'abc' found
$ echo "abcdefg" | ./a.out
input: 'abcdefg' not found
For reference:
http://en.cppreference.com/w/cpp/container/vector
http://en.cppreference.com/w/cpp/string/basic_string
http://en.cppreference.com/w/cpp/string/basic_string/getline
http://en.cppreference.com/w/cpp/language/string_literal
Why is "using namespace std" considered bad practice?
http://en.wikipedia.org/wiki/Binary_search_tree
http://en.wikipedia.org/wiki/Hash_table
http://en.cppreference.com/w/cpp/container/set
http://en.cppreference.com/w/cpp/container/set/find
http://en.cppreference.com/w/cpp/container/unordered_set
http://en.cppreference.com/w/cpp/container/unordered_set/find
http://en.wikipedia.org/wiki/Computational_complexity_theory

How do I check for stored "\t" in a string?

Can someone explain to me how to properly search for a "tab" character stored in a string class?
For example:
text.txt contents:
std::cout << "Hello"; // contains one tab space
User enters on prompt: ./a.out < text.txt
main.cpp:
string arrey;
getline(cin, arrey);
int i = 0;
while( i != 10){
if(arrey[i] == "\t") // error here
{
std::cout << "I found a tab!!!!"
}
i++;
}
Since there is only one tab space in the textfile, I am assuming it is stored in index [0], but the problem is that I can't seem to make a comparison and I don't know any other way of searching it. Can someone help explain an alternative?
Error: ISO C++ forbids comparison between pointer and integer
First of all, what is i? And secondly, when you use array-indexing of a std::string object, you get a character (i.e. a char) and not a string.
The char is converted to an int and then the compiler tries to compare that int with the pointer to the string literal, and you can't compare plain integers with pointers.
You can however compare a character with another character, like in
arrey[i] == '\t'
std::string::find() might help.
Try this:
...
if(arrey.find('\t') != string::npos)
{
std::cout << "I found a tab!!!!";
}
More info on std::string::find is available here.
Why not using what C++ library provides? You could do it like this:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string arrey;
getline(cin, arrey);
if (arrey.find("\t") != std::string::npos) {
std::cout << "found a tab!" << '\n';
}
return 0;
}
The code is based on this answer. Here is the ref for std::find.
About your edit, how are sure that the input is going to be 10 positions? That might be too little or too big! If it is less than the actual size of the input, you won't look all the characters of the string and if it is too big, you are going to overflow!
You could use .size(), which says the size of the string and use a for loop like this:
#include <iostream>
#include <string>
using namespace std;
int main() {
string arrey;
getline(cin, arrey);
for(unsigned int i = 0; i < arrey.size(); ++i) {
if (arrey[i] == '\t') {
std::cout << "I found a tab!!!!";
}
}
return 0;
}

Read command line from char

I want to create a program capable of reading the command line in format:
SET x = ( expression ) <--- spaces between everywhere
without using strings. I wanted to cin in the command and simply compare it to a list of possible values,
so..
char a;
cin>>a;
if(a== 'SET'){
----
}
this obviously does not work because a is an array.
I thought i could do it this way (if a[0]=='S'), then check a[1] for 'E' etc. but I believe this is a widely inefficient way of doing this? or isnt it?
For your example, you can use std::string
std::string a;
cin >> a;
if (a.compare("SET"))
{
// do stuff
}
string::compare will do an equality comparison for the full string instead of character-by-character comparison.
You can use the strcmp function:
#include <iostream>
#include <cstring>
int main(int argc, char* argv[]) {
char * a;
std::cin >> a;
if (strcmp(a, "SET") == 0) {
std::cout << "check" << std::endl;
}
return 0;
}

C++ comparing the index of a string to another string?

How can I compare a single character from a string, and another string (which may or may not be greater than one character)
This program gives me almost 300 lines of random errors. The errors don't reference a specific line number either, just a lot of stuff about "char* ", "", or "std::to_string".
#include <iostream>
#include <string>
using std::cout;
using std::string;
int main() {
string str = "MDCXIV";
string test = "D";
if (test == str[4]) { // This line causes the problems
cout << test << endl;
}
return 0;
}
str[4] is a char type, which will not compare with a string.
Compare apples with apples.
Use
test[0] == str[4]
instead.
You need to convert str[4] (which is a char) to a string before you can compare it to another string. Here's a simple way to do this
if (test == string(1, str[4])) {
You're comparing a char to a std::string, this is not a valid comparison.
You're looking for std::string::find, as follows:
if( test.find( str[4] ) != std::string::npos ) cout << test << "\n";
Note that this will return true if test contains str[4].
You're mixing types. It doesn't know how to compare a string (test) to a char (str[4]).
If you change test to a char that will work fine. Or reference the specific character within test you want to compare such as if (test[0] == str[4]) it should compile and run.
However, as this is merely an example and not really the true question what you'll want to do is look at the functionality that the std::string class supplies
Also you need "D" to be a char value not a string value if you are comparing it like that.
std::string myString = "Hello World";
const char *myStringChars = myString.c_str();
You have to turn it into a char array before can access it. Unless you do.
str.at(i);
which you can also write as
str[i] <-- what you did.
Essentially, this all boils down to test needs to initialized like char test = 'D';
Final Output..
#include <iostream>
#include <string>
using std::cout;
using std::string;
int main() {
string str = "MDCXIV";
char test = 'D';
if (test == str[4]) { // This line causes NO problems
cout << test << endl;
}
return 0;
}
I think you might be mixing python with c++. In c++ 'g' refers to a single character g not a string of length 1. "g" refers to an array (string) which is 1 character long and looks like ['g']. So as you can see, if you compare a single character to an array of characters no matter if the array is a single character long, this operation is not defined.
This will work if define it yourself by building a class which is able to compare string of one character long to a single character. Or just overload the == operator for doing just that
Example:
#include <iostream>
#include <string>
using std::cout;
using std::string;
using std::endl;
bool operator == ( const string &lh, const char &rh) {
if (lh.length() == 1) return lh[0] == rh;
return 0;
}
int main() {
string str = "MDCXIV";
string test = "D";
if (test == str[4]) {
cout << test << endl;
}
else cout << "Not a match\n";
return 0;
}

How can I check if a number (double type) stored as a string is a valid double number in C++?

I'm having an issue with a program I'm working on in C++. I am asking the user to input a valid number. I take it in as a string because the particular assignment I'm doing, it makes it easier in the long run. For basic error checking, I want to check to see if the number entered is a valid number. Example:
Enter number: 3.14
This would be valid
Enter number: 3.1456.365.12
This shouldn't be valid
use strtod, which converts a string to a double and returns any characters it couldn't interpret as part of the double.
double strtod(const char* nptr, char** endptr)
Like this:
char* input = "3.1456.365.12";
char* end;
strtod(input, &end);
if (*input == '\0')
{
printf("fail due to empty string\n");
}
if (end == input || *end != '\0')
{
printf("fail - the following characters are not part of a double\n%s\n", end);
}
I think boost::lexical_cast should help you here
An example using only standard C++:
#include <sstream>
// ...
double dbl = 0.0;
std::istringstream num("3.1456.365.12");
num >> dbl;
if(!num.fail() &&
num.eof()) // This second test is important! This makes sure that the entire string was converted to a number
{
// success
}
else
{
// failure
}
Bonus generic template function version:
#include <sstream>
#include <string>
#include <exception>
// Version that throws an exception on a bad parse:
template <typename T>
T parse(const std::string& str)
{
T value;
std::istringstream parser(str);
parser >> value;
if(!parser.fail() && parser.eof())
{
return value;
}
else
{
throw "bad lexical cast";
}
}
// usage:
double foo = parse<double>("3.14234");
// Non-exception, error code version
template <typename T>
bool parse(const std::string& str, T& value)
{
std::istringstream parser(str);
parser >> value;
return (!parser.fail() && parser.eof());
}
// usage:
double foo = 0.0;
bool success = parser<double>("3.11234", foo);
If you have no boost, you always can use strtod
You can use strtoX (where X is f for float, l for long, ul for unsigned long, etc.), choosing for the kind of number you want. One of the parameters you give it is an "end pointer", which points to the first character in the string that could not be converted into the target number type.
In your case, what you're apparently looking for is that the end pointer should be at the end of the string, indicating that all characters in the string were converted to the target type.
Edit: Sorry, didn't notice that you'd mentioned 'double' in the title (but not the question itself). That being the case, you'd use strtod, as a couple of others have also advised.
The best way is to make an actual attempt to convert your string to double using any of the standard and/or idiomatic ways to do the conversion, and check for errors afterwards. In C that would be functions from strto... group (which are, of course, perfectly usable in C++ as well). In C++ you can use stream-based conversion idiom.
One thing to watch for though is that the common convention in standard conversion methods is to convert "as much as possible" and not consider any extra characters as an error. For example, a string "123abc" is normally considered valid input, with only "123" part getting converted. All usable methods provide you with the way to detect the fact that there is something extra after the actual number, if you want to treat this situation as an error. But it is up to you to take the additional steps to perform this verification.
A simple option is to use the sscanf function:
const char * num_as_str = "3.1416";
double num;
if(std::sscanf(num_as_str, "%lg", &num) == 1)
{
std::cout << "You correctly entered the number " << num << "\n";
}
If you want to get fancy you can use istringstream:
std::istringstream iss(num_as_str);
if(iss >> num)
{
std::cout << "You correctly entered the number " << num << "\n";
}
If you want to get extra-fancy you can use boost's lexical_cast:
try
{
num = boost::lexical_cast<double>(num_as_str);
}
catch(boost::bad_lexical_cast &)
{
std::cout << "What you entered is not a proper number" << num << "\n";
}
Ah, I loved these assignments. A good old hand written lexer is the way to go (since you are still in the begining days -- don't try to use boost just yet). They are fast, easy to write and extremely fun to play with. If you can get a copy of Levine's book on Lex/Yacc, look up the first couple of chapters for ideas.
As mentioned by AndreyT, the best way is to attempt to convert the string into a float and check for an error. Personally I would opt to use std::istringstream, as you're using C++. Something like the following should work:
float ff;
std::istringstream istr;
std::string input("1234.5678");
// set the stream to have your string as its base
istr.str(input);
// now try to read the number:
istr >> ff;
if (istr.fail())
{
// some error in the parsing
}
istringstream is part of STL, so you shouldn't need any additional libraries, and it will also with with exceptions if that's your choice. More information can be found here: http://www.cplusplus.com/reference/iostream/istringstream/
You could use regular expressions. Since you already have a string, it would be easy to compare that with this regex:
/^\d+(\.\d+)?$/
The library regex.h can help you here. See this: regex.h
This is my quick hack :)
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
template <typename T>
bool fromStr(const std::string& str, T& var)
{
std::stringstream convertor;
convertor << str;
convertor >> var;
if( convertor.fail() )
return false;
char c = static_cast<char>( convertor.get() );
return convertor.eof() || c == '\n' || c == ' ' || c == '\t';
}
int main()
{
double d;
std::string str = "5.04146.55";
if( fromStr<double>(str, d) )
{
std::cout << "Valid conversion!, d = " << d;
}
else
{
std::cout << "Invalid conversion!";
}
}