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).
Related
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.
Problem:
I was trying to encrypt a std::string password with a single rule:
Add "0" before and after a vowel
So that bAnanASplit becomes b0A0n0a0n0A0Spl0i0t.
However, I got stuck in an infinite loop.
Here is the code:
const std::string VOWELS = "AEIOUaeiou";
std::string pass = "bAnanASplit";
//Add zeroes before and after vowels
for (int i = 0; i < pass.length(); ++i)
{
i = pass.find_first_of(VOWELS, i);
std::cout << pass << "\n";
if(i != std::string::npos)
{
std::cout << pass[i] << ": " << i << "\n";
pass.insert(pass.begin() + i++, '0');
pass.insert(pass.begin() + ++i, '0');
}
}
...And the result:
bAnanASplit
A: 1
b0A0nanASplit
a: 5
b0A0n0a0nASplit
A: 9
b0A0n0a0n0A0Split
i: 15
b0A0n0a0n0A0Spl0i0t
b0A0n0a0n0A0Spl0i0t
A: 2
b00A00n0a0n0A0Spl0i0t
a: 8
b00A00n00a00n0A0Spl0i0t
A: 14
b00A00n00a00n00A00Spl0i0t
i: 22
b00A00n00a00n00A00Spl00i00t
b00A00n00a00n00A00Spl00i00t
...
Any help? This sure seems strange.
Edit: All the answers were useful, and therefore I have accepted the one which I think best answers the question. However, the best way to solve the problem is shown in this answer.
Never, ever, modify the collection/container you are iterating upon!
Saves you a lot of trouble that way.
Let's start with your code and generate a new string with vowels surrounded by 0.
const std::string VOWELS = "AEIOUaeiou";
std::string pass = "bAnanASplit", replacement;
//Add zeroes before and after vowels
for (auto ch : pass)
{
if(VOWELS.find(ch) != std::string::npos)
replacement += '0' + ch + '0';
else
replacement += ch;
}
And there you have it!
As the OP seems to look for the exact reason for the misbehavior, I thought to add another answer as the existing answers do not show the exact issue.
The reason for the unexpected behavior is visible in following lines.
for (int i = 0; i < pass.length(); ++i)
{
i = pass.find_first_of(VOWELS, i);
...
Problem 1:
The loop counter i is an int (i.e. a signed int). But std::string::find_first_of returns std::string::npos if there's no match. This is usually the maximum number representable by an unsigned long. Assigning a huge unsigned value to a shorter signed variable will store a totally unexpected value (assuming you are not aware of that). In this case, i will becomes -1 in most platforms (try int k = std::string::npos; and print k if you need to be sure). i = -1 is valid state for the loop condition i < pass.length(), so the next iteration will be allowed.
Problem 2:
Closely related to the above problem, same variable i is used to define the start position for the find operation. But, as explained, i will not represent the index of the character as you would expect.
Solution:
Storing a malformed value can be solved by using the proper data type. In the current scenario, best options would be using std::string::size_type as this is always guaranteed to work (most probably this will be equal to size_t everywhere). To make the program work with the given logic, you will also have to use a different variable to store the find result.
However, a better solution would be using a std::stringstream for building the string. This will perform better than modifying a string by inserting characters in the middle.
e.g.
#include <iostream>
#include <sstream>
int main() {
using namespace std;
const string VOWELS = "AEIOUaeiou";
const string pass = "bAnanASplit";
stringstream ss;
for (const char pas : pass) {
if (VOWELS.find(pas) == std::string::npos) {
ss << pas;
} else {
ss << '0' << pas << '0';
}
}
cout << pass << "\n";
cout << ss.str() << endl;
}
You are not exiting the loop in case i becomes std::string::npos. So, the i value is changed to some unexpected value (likely something like -1) when it gets to the position of last i or 0 after i(here I am referring to i of split). This is because i is an signed integer but in this case find_first_of() returns std::string::npos which is largest value that can be held by a size_t. In that case the terminating condition i < pass.length() may hold true and the loop continues. So, I am recommending following changes in your code -
for (size_t i = 0; i < pass.length(); ++i)
{
i = pass.find_first_of(VOWELS, i);
if(i == std::string::npos)
break;
pass.insert(pass.begin() + i++, '0');
pass.insert(pass.begin() + ++i, '0');
}
On the same note if (i != std::String::npos) does not do what you are expecting it to do.
But then again it better not to modify the container while you are iterating over it which #Tanveer mentioned in his answer
This question already has answers here:
Convert single char to int
(3 answers)
Closed 3 years ago.
I have a string which has 5 characters. I want to convert each single character to int and then multiply them with each other. This is the code :
int main()
{
int x;
string str = "12345";
int a[5];
for(int i = 0; i < 5; i++)
{
a[i] = atoi(str[i]);
}
x = a[0]*a[1]*a[2]*a[3]*a[4];
cout<<x<<endl;
}
It gives this error for the line with atoi :
invalid conversion from 'char' to 'const char*' [-fpermissive]|
How can I fix this? Thanks.
You can use:
a[i] = str[i] - '0';
Does a char to digit conversion by ASCII character positions.
The proper way to do this is std::accumulate instead of rolling your own:
std::accumulate(std::begin(str), std::end(str), 1, [](int total, char c) {
return total * (c - '0'); //could also decide what to do with non-digits
});
Here's a live sample for your viewing pleasure. It's worth noting that the standard guarantees that the digit characters will always be contiguous, so subtracting '0' from any of '0' to '9' will always give you the numerical value.
std::atoi takes a const char*(a null terminated sequence of characters)
Try to change like
a[i]= str[i]-'0';
You are supplying with a single char hence the compiler is complaining
str[i] is char not char *
Use following :-
int x;
std::string str = "12345";
int a[5];
for(int i = 0; i < 5; i++)
{
a[i] = str[i] -'0' ; // simply subtract 48 from char
}
x = a[0]*a[1]*a[2]*a[3]*a[4];
std::cout<<x<<std::endl;
look at this way
string str = "12345";
int value = atoistr.c_str());
// then do calculation an value in a loop
int temp=1;
while(value){
temp *= (value%10);
value/=10;
}
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.
#include <iostream>
#include <math.h>
#include <iomanip>
#include <sstream>
#include <stdio.h>
#include <string>
#include <stdlib.h>
using namespace std;
int main()
{
ostringstream str;
double num = pow(2,1000);
int sum = 0;
str << setprecision(1000) << num;
string here = str.str();
cout << here << "\n\n";
/*for(int i = 0; i < here.length(); i++)
{
sum += atoi(&here[i]);
}*/
cout << atoi(&here[0]);
cout << atoi(&here[1]);
cout << atoi(&here[2]);
}
output:
10715086071862673209484250490600018105614048117055336074437503883703510511249361
22493198378815695858127594672917553146825187145285692314043598457757469857480393
45677748242309854210746050623711418779541821530464749835819412673987675591655439
46077062914571196477686542167660429831652624386837205668069376
000
Why all 0s?
Going out on a limb here and assuming you don't actually want to use std::atoi. If you want to sum every digit in a string, you want to convert the digit character into its digit value. The quickest way to do this is to subtract the character constant '0'. In your loop, simply use:
for(int i = 0; i < here.length(); i++)
{
sum += here[i] - '0';
}
This is possible because subtracting the '0' from the various characters in the string results in the numeric value that the character represents.
'0' - '0' == 0
'1' - '0' == 1
'2' - '0' == 2
//etc
'9' - '0' == 9
As far as I can remember, the C++ standard does not force any particular encoding, but it does specify that the digit characters must be contiguous so while the above is safe when the string contains only digits, the subtraction on other characters that may appear in the string will throw off your result:
'E' - '0' == ???
'.' - '0' == ???
'+' - '0' == ???
That's how std::atoi indicates an error. In this case, the error is that the numeric value in the array is larger than the largest possible integer (which is technically undefined behavior with atoi, but your implementation apparently treats it as any other error)
atoi converts a string to an integer (probably 32-bits or 64-bits on your platform).
The number you have stored in here is larger than INT_MAX, so atoi returns zero:
On success, the function returns the converted integral number as an int value. If no valid conversion could be performed, a zero value is returned.
EDIT: actually, didn't even read my own link carefully enough, apparently it's undefined behavior in this case
There is no standard specification on what happens when the converted value would be out of the range of representable values by an int.
from www.cplusplus.com
'here[0]' returns the first character of 'here' as a char.
'&here[0]' returns the address of 'here[0]'. You're not wanting the address. '&' is for getting the address of a variable.
std::atoi(here[0]) returns the first character of here as a char, and converts that char to an int... or would, if 'atoi' handled chars. It doesn't - it handles arrays of chars. Giving it one char probably wouldn't compile.
std::atoi(&here[0]) compiles, but isn't what you want. atoi will keep reading chars until it reaches a null character.
It means that given the string "567321":
std::atoi(&here[0]) would return "987654321"
std::atoi(&here1) would return "87654321"
std::atoi(&here2) would return "7654321"
std::atoi(&here[3]) would return "654321"
... and so on.
If you are really wanting to sum all the numbers, and are required to use std::atoi(), then you can do it using std::string::substr():
for(int i = 0; i < here.length(); i++)
{
std::string subString = here.substr(i,1); //Returns a substring starting at 'i', and including 1 character
sum += atoi(subString.c_str());
}
A better way is to use the method #dreamlax posted... but if you are learning about strings and std::atoi, learning about std::string::substr() is important to know.
If you are using C++11, you'd rewrite it using std::stoi:
for(int i = 0; i < here.length(); i++)
{
std::string subString = here.substr(i,1); //Returns a substring starting at 'i', and including 1 character
sum += std::stoi(subString);
}