Problem Solved: StringVariable[position] (in this case Word[e]) outputs a value that is defined as a char variable type rather than the string variable type I had expected it to. Thank you all for your help!
When I run my Hangman game I get the following error:
Error 2 error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion)
Error 1 error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion)
4 IntelliSense: no operator "!=" matches these operands
3 IntelliSense: no operator "==" matches these operands
I commented in the code where this error points to and copied in the functions related to the problem. The functions were then run in the main() function to simplify the code.
This section of the code is meant to check if the guess is equal to the letter in the word. Let me know if I need to provide further explanation.
Related Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
//Functions
void GrabWord();
void DiscoverLet();
void guess();
//Variables
int NumL, Fl, F, count[10];
string G, Word;
//Grab Word from .txt and define NumL
void GrabWord()
{
//Grab Random Line from .txt
//Random Line >> Larray
Word = "short";
NumL = Word.size();
}
//Checks if Guess matches any letters
void DiscoverLet()
{
for(int e = 0; e < NumL; e++)
{
//Error Points to the following two comparisons
if(G == Word[e])
{
count[e] = 1;
}
else if(G != Word[e])
{
Fl++;
}
else
{
cout << "Error: DiscoverLet(), G to Word[]\n";
}
}
if(Fl == NumL)
{
F = F + 1;
}
Fl = 0;
}
The proper string comparison that you are looking for is called find:
if(Word.find(G) > std::string::npos)
{
count[e] = 1;
}
else
{
Fl++;
}
The reason why your comparison does not work was that you Word[e] was grabbing a character of the string and it was being compared to a string variable.
Judging by your code it looks like you wanted to count the number of times the letter appears in the string. If you wanted to count the number of times the letter appears in the string then you can use the find function like this:
int count = 0;
int foundIdx = 0;
for(int i = 0; i < NumL; i++)
{
foundIdx = Word.find(G, foundIdx+1);
if (foundIdx == std::string::npos)
{
break;
}
count++;
}
if(G == Word[e])
...
else if(G != Word[e])
In these comparisons, G is a string and Word[e] is a character in a string. There is no operator to perform the respective comparisons.
G is a variable of type string. Word is also a type of string. So as you might already know that strings are nothing but array of chars. So Word[e] points to a character of the Word string. So
if(G == Word[e])
Here, you are comparing a string with a character. But C++ has no idea how to do that! I mean C++ does not know how to evaluate the expression. Because the operator == for comparing a string and a char is not overloaded inside string class. Same goes for the line
if(G != Word[e])
If you're trying to find out if Word[e] character appears in the G string, you should run another loop searching character by character of the string G. Or you can use find function.
The reason of the error is because you are comparing string to a character. You can use ==, !=, >, <, etc on character, but certainly not strings. And also, the string G appears to be empty. Hope this helps and correct me if I'm wrong! Happy coding!
G is string type but Word[e] is char type. You should convert Word[e] to String to compare with G by std::to_string or use method string::find with G to find content Word[e] in G.
The comparison won't work that way. You need to understand what is the difference between a char and a std::string. A variable of type char represent a single letter. A char cannot be multiple character, and cannot be empty. Is strictly one, single letter. Nothing less, nothing more.
A std::string can be seen as a managed array of char. It's size can be 0 to very big. This type expose the array access operator, the [n], and that operator returns a character from the string at position n. It's return type is char.
Since G is supposed to be an input letter from the user, I'd suggest you to declare G as a char. In fact, it will solve your problem.
The reason for that a string cannot be compared to a single character. A string is designed to be comparable to another whole string. And a character can be compared with another integral, or put it simpler, another char. So if you change the type of G to char, your comparison will work as expected.
Related
Context: I am making myself a password generator in c++, basically it uses rand to generate numbers, and these numbers correspond directly to ASCII characters.
So, generating the numbers is easy, but i need to convert this to their ASCII equivalents to actually make a usable password.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main ()
{
//Initializing variables.
int type = 0;
int character = 0;
char print = character;
//Generator.
srand(time(NULL));
for (int i=0; i<10;i++)
{
type = rand()%(3-1+1)+1;//Determines: 1 = Uppercase, 2 = Lowercase, 3 = Number.
if (type == 1)//If Uppercase.
{
character = rand()%(90-65+1)+65;//Determines Uppercase character to be generated.
cout<<print<<endl;
}
if (type == 2)//If Lowercase.
{
character = rand()%(122-97+1)+97;//Determine Lowercase character to be generated.
cout<<print<<endl;
}
if (type == 3)//If Numerical.
{
character = rand()%(57-48+1)+48;//Determines Number to be generated.
cout<<print<<endl;
}
}
}
In the code i posted above, you can see i last tried blatantly telling the program that the variable "character" needs to be used as an actually character.
Ok so there seems to be a bit of confusion.
Rand generates a number say between 65 and 90. These numbers correspond to capital letters on the ASCII table. I want to print to the console the letter, not the generated number.
When you write this
char print = character;
you tell the compiler that you want it to initialize variable print to the current value of variable character (which happens to be zero at the time). If you want the current value to be set to a variable of different type, you need to do it after a reassignment of character:
character = rand()%(90-65+1)+65;//Determines Uppercase character to be generated.
print = (char)character;
cout<<print<<endl;
You do not have to do reassignment, though, because a cast directly before printing will be sufficient:
character = rand()%(90-65+1)+65;//Determines Uppercase character to be generated.
cout<<(char)character<<endl;
Note: although it is fine to use decimal values of ASCII characters, the code becomes easier to read if you use character constants instead:
character = rand()%('Z'-'A'+1)+'A';
may be try by replacing
cout<<print<<endl;
by
cout<<(char)character;
Then you will understand what you missed.
In addition to Jay Kumars answer this is I believe an implicit/explicit conversion
Here is an example I tested with my code, it functions to this end.
for (int i = 0; i < size; ++i) {
cout << (char)('0' + 17 + i) << "-->\t"; // implicit conversion
}
I've tried to make a loop to get the first number after y=
but sometimes the value of term1coffs is: 65(
and sometimes the value is: 65 without the bracket ?!
std::string fx = cwin.get_string("Enter a polynomial formula that has a form like this: y=1(x^3)+2(x^2)+0.5(x^1)+1");
std::string j;
//j is a condition to end for loop
int n=2;
std::string term1coffs;
//to get the number before the bracket y= ?? ( X^.....
for (j=fx.substr(n,1);j=="(";n+0)
{
n=n+1;
}
term1coffs=fx.substr(2,n);
double term1coff= atof(term1coffs.c_str());
Traditional parsers do something like this (written in pseudocode):
do
{
get a character
if (character is operator)
{
store character as operator
convert operand to double
if conversion succeeded
store operand value
else
store operand as variable name
operand = "";
}
else
{
add current character to operand
}
} while(there is more to do)
If you want to later use the parsed results to perform calculations, you probably want to produce tree-structure, based on order of precedence, taking into account parenthesis. The basic principle for this is the Shunting-Yard Algorithm
I'm working on an assignment where we have to create a "MyInt" class that can handle larger numbers than regular ints. We only have to handle non-negative numbers. I need to overload the >> operator for this class, but I'm struggling to do that.
I'm not allowed to #include <string>.
Is there a way to:
a. Accept input as a C-style string
b. Parse through it and check for white space and non-numbers (i.e. if the prompt is cin >> x >> y >> ch, and the user enters 1000 934H, to accept that input as two MyInts and then a char).
I'm assuming it has something to do with peek() and get(), but I'm having trouble figuring out where they come in.
I'd rather not know exactly how to do it! Just point me in the right direction.
Here's my constructor, so you can get an idea for what the class is (I also have a conversion constructor for const char *.
MyInt::MyInt (int n)
{
maxsize = 1;
for (int i = n; i > 9; i /= 10) {
// Divides the number by 10 to find the number of times it is divisible; that is the length
maxsize++;
}
intstring = new int[maxsize];
for (int j = (maxsize - 1); j >= 0; j--) {
// Copies the integer into an integer array by use of the modulus operator
intstring[j] = n % 10;
n = n / 10;
}
}
Thanks! Sorry if this question is vague, I'm still new to this. Let me know if I can provide any more info to make the question clearer.
So what you basically want is to parse a const char* to retrieve a integer number inside it, and ignore all whitespace(+others?) characters.
Remember that characters like '1' or 'M' or even ' ' are just integers, mapped to the ASCII table. So you can easily convert a character from its notation human-readable ('a') to its value in memory. There are plenty of sources on ascii table and chars in C/C++ so i'll let you find it, but you should get the idea. In C/C++, characters are numbers (of type char).
With this, you then know you can perform operations on them, like addition, or comparison.
Last thing when dealing with C-strings : they are null-terminated, meaning that the character '\0' is placed right after their last used character.
so if i were to enter patricia(don't worry im converting it toupper) that string would be loaded into my vector.
My question is about the find functions. i am counting down characters correct? so if i were to enter patricia and j would be on ABBOT, PATRICIA the value in comma would be 5. Ok im good so far, but what happens in my found variable?
bool NameSearch::findFirstNames(vector<string> &vsFirst, string name)
{
int j = 0;
bool bName = false;
vsFirst.clear();
while(j < total)
{
int comma;
comma = names[j].find(',');
//Confused here
int found = names[j].find(name, comma);
if(found > -1)
{
vsFirst.push_back(names[j]);
bName = true;
}
j++;
}
return bName;
}
The if (found > -1) test probably works on your platform but is technically dubious.
The return type of std::string::find() is std::string::size_type, and if the substring you're searching is not found, the returned value is std::string::npos (on the other hand, if the substring is found, the returned value is the character index of its first occurrence).
Now the std::string::npos value happens to be the greatest possible value of type std::string::size_type, and if that is unsigned int on your implementation, that means the comparison with the signed int -1 will yield true.
However, no assumptions can be made in general on the type of std::string::size_type Thus, I suggest to rewrite the test as:
if (found != std::string::npos)
{
...
}
This is misleading code. std::string::find() returns a size_t, not an int.
int comma;
comma = names[j].find(',');
This is misleading code. When std::string::find() fails, it returns std::string::npos, not -1. In your environment, it's equivalent to -1 by coincidence.
if(found > -1)
The if statement is effectively trying to check "if a result was found" by making sure it isn't std::string::npos.
There are two other answers, that point out what is wrong with this code, but I feel like none of them explains to you, what the author was doing, and that's the explanation you want. :)
Let's look at the following snippet first.
int comma;
comma = names[j].find(',');
As pointed out, it should be rewritten as:
size_t comma;
comma = names[j].find(',');
There are 4 overloads of the find method in the std::string
The code above uses this one:
size_t find (char c, size_t pos = 0) const;
It returns the index, at which the character passed as the first argument (in your case it's ',') appears in the string or std::string::npos if that character isn't found. Apparently the author is sure the ',' character must be present in the string names[j] and doesn't check the result.
In the line:
int found = names[j].find(name, comma);
which again should be rewritten as:
size_t found = names[j].find(name, comma);
the following overload of the find method is used:
size_t find (const string& str, size_t pos = 0) const;
This one searches the string names[j] for the first occurrence of the string passed as the first argument (in your case name) and returns the index at which the match starts if there is a match or std::string::npos otherwise.
As you can see, both mentioned overloads of the find method have a second parameter with default value of 0. This second parameter allows a user to specify, at what index to start the search in the searched string (in your case names[j])
The call:
comma = names[j].find(',');
is equivalent to the call:
comma = names[j].find(',', 0);
and it means: look for the character ',' int the string names[j] starting from the beginning and return the index of the first occurrence of that character or std::string::npos, if there is no such character in that string.
The call:
size_t found = names[j].find(name, comma);
means: look for the substring equal to name in the string names[j], but start from the position where the comma was found and return the index of the first occurrence of that substring or std::string::npos if there is no such substring in that string, after the comma.
Maybe comma_position instead of comma would have been a better name for the variable.
I thought I would try and write some encryption program that converts input to numbers in a file.
I made a table, giving each letter its own number. The code itself went a little like this for each letter:
if (Letter = "P")
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
It came up with "cannot convert from 'const char [2]' to 'char'"
Can anyone suggest how I would go about actually getting a number from a letter?
If Letter is a char, use a char literal:
if (Letter == 'P')
...
Your conditional checking is wrong. It should be ==, not =. A single = means assignment whereas a == means conditional checking.
I am assuming Letter is a character array. In that case, you can use strcmp to compare it with P.
if(strcmp(Letter, "P") == 0)
{
// rest of the code
}
Take a look at the strcmp function reference here, if necessary.
If Letter is simply a char, then you need to compare it with P like this -
if(Letter == 'P')
{
// rest of the code
}
A single quote around a character makes it a character literal, which then can be compared against another character using ==.
You can not compare C++ char to C++ string! You should use single quote for chars, not double quotes. Also, the C++ equals operator is not =, it is ==. the single = is the assignment operator.
You should write the condition like this :
if (Letter == 'P')
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
(Letter = "P")
This is an assignment, not comparison.
You probably meant (Letter == "P") which would also be wrong, you need strcmp.
you need to use strcmp to compare....as = is an assignment operator....
I would recommend that when you give us an error message as you did, you give us the full message - including line numbers so that we know where the error occurred (or tell us what line it occurred at). Paying attention to those line numbers can greatly help finding the true problem.
Given the error message I'm assuming Letter is of type char - you need to understand the difference between literal strings (enclosed in double quotes) and literal characters (enclosed in single quotes).
As Luchian also mentioned, you have an assignment rather than an equality test - unlike Visual Basic, if that is where you're coming from, the two have different symbols.
That should thus be:
if (Letter == 'P')