This question already has answers here:
Multi-character constant warnings
(6 answers)
Closed 2 months ago.
void addItem(char selection) {
double total = 0.0;
qty = 0;
cout \<\< "Enter Qty: ";
cin \>\> qty;
`else if (selection == '10') {
total = 60 * qty;
cout << "Added to order"<<endl;
Iattotal += total;
Iatqty += qty;
Gtotal += Iattotal;
}
}
main.cpp:93:22: warning: multi-character character constant \[-Wmultichar\]
93 | if (selection == '10') {
| ^\~\~\~
^\~\~\~
It's there any solution for this peoblem I tried to change char to int but it didn't changed and i tried to find similar problems but it didn't fixed
Depends on what you want to do:
to read the value as an ascii code, you can write
char a = 'a';
int ia = (int)a;
/* note that the int cast is not necessary -- int ia = a would suffice */
to convert the character '0' -> 0, '1' -> 1, etc, you can write
char a = '4';
int ia = a - '0';
/* check here if ia is bounded by 0 and 9 */
The error is being produced because you are comparing a the "selection" variable, which is a char type, and can hold only one character, to '10' which is a multi-character constant.
If you are trying to pass a multi character variable, such as user input, to the function you might consider using a std:string.
Std::string can hold multiple characters, and can be compared using the == operator.
Alternatively, you could change the type to char * - this is how c-strings are normally defined. C-Strings are null terminated to denote the end of the string.
If you are using a c-string, you would need to use a library function like strcmp to compare the value to the constant.
strcmp returns 0 when the two strings are equal.
When dealing with c-strings you have to be careful not to read beyond the size of the buffer or array. For safety it is better to use strncmp, where the maximum number of characters to be compared can be specified.
Related
I want to convert an index in a string to an int in order to populate a 2D array of type int.
string s = "1 2 3";
a[0][0] = s.at(0);
I want a[0][0] to store the int value 1, but right now it's storing 49 with this method (which I am assuming is the direct conversion).
I have tried atoi, stoi, and static_cast, but I was getting a conversion error.
When you use
a[0][0] = s.at(0);
you are assigning the value of the character '1' to a[0][0], which is represented by the integral value of 49 in ASCII encoding.
If you are certain that there is only one digit, you can use
a[0][0] = s.at(0) - '0';
You can use a more flexible strategy.
std::istringstream str(s);
str >> a[0][0];
Gave wrong answer before:
This should work:
using namespace std;
int main ()
{
string str ("3");
int i = str.at(i) - 48;
cout << i <<endl;
return 0;
}
So, I am trying to figure out the best/simplest way to do this. For my algorithms class we are supposed read in a string (containing up to 40 characters) from a file and use the first character of the string (data[1]...we are starting the array at 1 and wanting to use data[0] as something else later) as the number of rotations(up to 26) to rotate letters that follow (it's a Caesar cipher, basically).
An example of what we are trying to do is read in from a file something like : 2ABCD and output CDEF.
I've definitely made attempts, but I am just not sure how to compare the first letter in the array char[] to see which number, up to 26, it is. This is how I had it implemented (not the entire code, just the part that I'm having issues with):
int rotation = 0;
char data[41];
for(int i = 0; i < 41; i++)
{
data[i] = 0;
}
int j = 0;
while(!infile.eof())
{
infile >> data[j+1];
j++;
}
for(int i = 1; i < 27; i++)
{
if( i == data[1])
{
rotation = i;
cout << rotation;
}
}
My output is always 0 for rotation.
I'm sure the problem lies in the fact that I am trying to compare a char to a number and will probably have to convert to ascii? But I just wanted to ask and see if there was a better approach and get some pointers in the right direction, as I am pretty new to C++ syntax.
Thanks, as always.
Instead of formatted input, use unformatted input. Use
data[j+1] = infile.get();
instead of
infile >> data[j+1];
Also, the comparison of i to data[1] needs to be different.
for(int i = 1; i < 27; i++)
{
if( i == data[1]-'0')
// ^^^ need this to get the number 2 from the character '2'.
{
rotation = i;
std::cout << "Rotation: " << rotation << std::endl;
}
}
You can do this using modulo math, since characters can be treated as numbers.
Let's assume only uppercase letters (which makes the concept easier to understand).
Given:
static const char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const std::string original_text = "MY DOG EATS HOMEWORK";
std::string encrypted_text;
The loop:
for (unsigned int i = 0; i < original_text.size(); ++i)
{
Let's convert the character in the string to a number:
char c = original_text[i];
unsigned int cypher_index = c - 'A';
The cypher_index now contains the alphabetic offset of the letter, e.g. 'A' has index of 0.
Next, we rotate the cypher_index by adding an offset and using modulo arithmetic to "circle around":
cypher_index += (rotation_character - 'A'); // Add in the offset.
cypher_index = cypher_index % sizeof(letters); // Wrap around.
Finally, the new, shifted, letter is created by looking up in the letters array and append to the encrypted string:
encrypted_text += letters[cypher_index];
} // End of for loop.
The modulo operation, using the % operator, is great for when a "wrap around" of indices is needed.
With some more arithmetic and arrays, the process can be expanded to handle all letters and also some symbols.
First of all you have to cast the data chars to int before comparing them, just put (int) before the element of the char array and you will be okay.
Second, keep in mind that the ASCII table doesn't start with letters. There are some funny symbols up until 60-so element. So when you make i to be equal to data[1] you are practically giving it a number way higher than 27 so the loop stops.
The ASCII integer value of uppercase letters ranges from 65 to 90. In C and its descendents, you can just use 'A' through 'Z' in your for loop:
change
for(int i = 1; i < 27; i++)
to
for(int i = 'A'; i <= 'Z'; i++)
and you'll be comparing uppercase values. The statement
cout << rotation;
will print the ASCII values read from infile.
How much of the standard library are you permitted to use? Something like this would likely work better:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
int rotation = 0;
std::string data;
std::stringstream ss( "2ABCD" );
ss >> rotation;
ss >> data;
for ( int i = 0; i < data.length(); i++ ) {
data[i] += rotation;
}
// C++11
// for ( auto& c : data ) {
// c += rotation;
// }
std::cout << data;
}
Live demo
I used a stringstream instead of a file stream for this example, so just replace ss with your infile. Also note that I didn't handle the wrap-around case (i.e., Z += 1 isn't going to give you A; you'll need to do some extra handling here), because I wanted to leave that to you :)
The reason your rotation is always 0 is because i is never == data[1]. ASCII character digits do not have the same underlying numeric value as their integer representations. For example, if data[1] is '5', it's integer value is actually 49. Hint: you'll need to know these values when handle the wrap-around case. Do a quick google for "ANSI character set" and you'll see all the different values.
Your determination of the rotation is also flawed in that you're only checking data[1]. What happens if you have a two-digit number, like 10?
I'm trying to count the total number of vowels in a string. I'm using strlen to get the total length of the string but then when I try and count through the string by each letter it says C++ forbids comparison. So I assume something is wrong in my if statement.
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char sentence[] = "";
int count;
int total;
int length;
int lengthcount;
int output;
output = 0;
length = 0;
count = 0;
total = 0;
cin >> total;
while (total != count){
cin >> sentence;
length = strlen(sentence);
while (length != lengthcount)
if (sentence[length] == "a" ||sentence[length] == "e"||sentence[length] == "i"||sentence[length] == "o"||sentence[length] == "u"||sentence[length] == "y"){
++ output;
++ lengthcount;
else{
++lengthcount;
}
}
++count;
}
return 0;
}
sentence[length] is a single character. It should be compared to a 'a' and not "a".
"a" is a character array and direct comparison with the built in operator== is not supported.
sentence[index] == 'a'; // where index is probably lengthcount in your example
Should do the trick. If use of std::string is an option, you should favour that over char arrays.
In addition, your char sentence[] = ""; will need some more space than just the '\0' character. Some alternatives include the use of std::string and std::getline or char[nnn] with cin.get(...) to make sure that you don't overrun the buffer you allocate.
See Nialls answer for one of the main problems.
The algorithmic problem with your code is again in the if statement.
sentence[length] returns the last character of your c_string (in this case, the null character '/0' that terminates the string).
Your if statement should look more like:
if (sentence[lengthcount] == 'a'\
||sentence[lengthcount] == 'e'\
||sentence[lengthcount] == 'i'\
||sentence[lengthcount] == 'o'\
||sentence[lengthcount] == 'u'\
||sentence[lengthcount] == 'y')
{
\\do something
}
Please remember to pre-allocate space for the string too, i.e.
char sentence[50];
which would give you space for 49 chars + terminator.
Alternatively, use a std::string
If you wish to count the total number of vowels in the given string, you need to use sentence[lengthcount]. Lets say the sentence is abc strlen(sentence) would return 3, and since in c++, the indexing begins with 0 and not 1, therefore sentence[length] would check for '\0' hence in the entire loop you check against the last value which is '\0' which is meaningless. Also, don't forget to initialize lengthcount. Rest all the things per-mentioned.
char sentence [] = "" produces an array sentence with a length of 1.
cin >> sentence isn't going to work very well, is it, if sentence cannot hold more than one character and one character is already needed for the trailing nul byte?
lengthcount is an unitialised variable, and the rest of the code just makes my head hurt.
This question already has answers here:
How to print (using cout) a number in binary form?
(13 answers)
Closed 9 years ago.
Why am I getting an error? It looks pretty straightforward to me. Also, is this the best method for doing what I'm trying to do?
#include <iostream>
#include <string>
int main() {
char j = "J";
std::cout << bitchar(j);
return 0;
}
std::string bitchar(char c) {
std::string s;
unsigned thisdivisor = (unsigned)c;
while (!thisdivisor) {
s += thisdivisor % 2 ? '0' : '1';
thisdivisor /= 2;
}
return s;
}
#include <iostream>
#include <string>
#include <bitset>
int main() {
char j = 'J';
std::cout << std::bitset<8>(j);
return 0;
}
Note:
"J" is a single character C-style string(with a trailing \0),
you should use 'J' for char.
Use std::bitset to print the bit pattern.
Try char j = 'j' instead of ="j" to assign a character to your variable. "j" is a string array.
You forgot to describe the error. Presumably it's something like
‘bitchar’ was not declared in this scope
because you didn't declare the function before you called it in main. Either move the definition of bitchar before main, or add a declaration before or inside main:
std::string bitchar(char c);
Then you'll probably get something like:
invalid conversion from ‘const char*’ to ‘char’
because you're trying to assign a string literal "J" to a character variable. Use a character literal 'J' (with single quotes) instead.
Then you'll find you're not getting any output. That's because while (!thisdivisor) loops as long as the value is zero; so it won't loop at all if you give it a non-zero value. You want while (thisdivisor) (or while (thisdiviser != 0) if you want to be more explicit), to loop while it's not zero.
Then you'll find that the bits are inverted; you want '0' if the modulo result is zero, while your test gives '0' if it is not zero:
s += thisdivisor % 2 ? '1' : '0';
or
s += (thisdivisor % 2 == 0) ? '0' : '1';
Finally, you might want to reverse the string (or build it by prepending rather than appending) to get the more conventional most-significant-bit-first ordering.
Answer 1: Why am I getting these errors
Try char j = 'J', as said by #losifM. The double-quote defines a character array, and you're looking for a single character (single quote).
Answer 2: What's a better way
A better way to do such a thing would be using an std::bitset, then stream it using cout.
//Add this
#include <bitset>
char j = 'j';
std::bitset<8> x(j);
std::cout << x;
Should be self explanatory at that point, but this may help: How to print (using cout) the way a number is stored in memory?
Sidenote:
s += thisdivisor % 2 ? '0' : '1';
should also be
s += thisdivisor % 2 ? '1' : '0';
because if thisdivisor % 2 returns 1 (true), you want it to add 1 to s, and vice-versa.
You are assigning char array (which decay to pointer) to char (J).
And then you initialize std::string with char (should be c-string).
The string input format is like this
str1 str2
I DONT know the no. of characters to be inputted beforehand so need to store 2 strings and get their length.
Using the C-style strings ,tried to made use of the scanf library function but was actually unsuccessful in getting the length.This is what I have:
// M W are arrays of char with size 25000
while (T--)
{
memset(M,'0',25000);memset(W,'0',25000);
scanf("%s",M);
scanf("%s",W);
i = 0;m = 0;w = 0;
while (M[i] != '0')
{
++m; ++i; // incrementing till array reaches '0'
}
i = 0;
while (W[i] != '0')
{
++w; ++i;
}
cout << m << w;
}
Not efficient mainly because of the memset calls.
Note:
I'd be better off using std::string but then because of 25000 length input and memory constraints of cin I switched to this.If there is an efficient way to get a string then it'd be good
Aside from the answers already given, I think your code is slightly wrong:
memset(M,'0',25000);memset(W,'0',25000);
Do you really mean to fill the string with the character zero (value 48 or 0x30 [assuming ASCII before some pedant downvotes my answer and points out that there are other encodings]), or with a NUL (character of the value zero). The latter is 0, not '0'
scanf("%s",M);
scanf("%s",W);
i = 0;m = 0;w = 0;
while (M[i] != '0')
{
++m; ++i; // incrementing till array reaches '0'
}
If you are looking for the end of the string, you should be using 0, not '0' (as per above).
Of course, scanf will put a 0 a the end of the string for you, so there's no need to fill the whole string with 0 [or '0'].
And strlen is an existing function that will give the length of a C style string, and will most likely have a more clever algorithm than just checking each character and increment two variables, making it faster [for long strings at least].
You do not need memset when using scanf, scanf adds the terminating '\0' to string.
Also, strlen is more simple way to determine string's length:
scanf("%s %s", M, W); // provided that M and W contain enough space to store the string
m = strlen(M); // don't forget #include <string.h>
w = strlen(W);
C-style strlen without memset may looks like this:
#include <iostream>
using namespace std;
unsigned strlen(const char *str) {
const char *p = str;
unsigned len = 0;
while (*p != '\0') {
len++;
*p++;
}
return len;
}
int main() {
cout << strlen("C-style string");
return 0;
}
It's return 14.