Can somebody clear me out why would I use union and with what purpose the same address for the cin'ed variable and bit field (task from the Schildts C++ book)? In other words why would I use union for :
char ch;
struct byte bit;
// Display the ASCII code in binary for characters.
#include <iostream>
#include <conio.h>
using namespace std;
// a bit field that will be decoded
struct byte {
unsigned a : 1;
unsigned b : 1;
unsigned c : 1;
unsigned d : 1;
unsigned e : 1;
unsigned f : 1;
unsigned g : 1;
unsigned h : 1;
};
union bits {
char ch;
struct byte bit;
} ascii ;
void disp_bits(bits b);
int main()
{
do {
cin >> ascii.ch;
cout << ": ";
disp_bits(ascii);
} while(ascii.ch!='q'); // quit if q typed
return 0;
}
// Display the bit pattern for each character.
void disp_bits(bits b)
{
if(b.bit.h) cout << "1 ";
else cout << "0 ";
if(b.bit.g) cout << "1 ";
else cout << "0 ";
if(b.bit.f) cout << "1 ";
else cout << "0 ";
if(b.bit.e) cout << "1 ";
else cout << "0 ";
if(b.bit.d) cout << "1 ";
else cout << "0 ";
if(b.bit.c) cout << "1 ";
else cout << "0 ";
if(b.bit.b) cout << "1 ";
else cout << "0 ";
if(b.bit.a) cout << "1 ";
else cout << "0 ";
cout << "\n";
}
As a union, both ch and bit have an overlapped (shared) memory location. Store a character in it as ch and then reading bit produces the corresponding bit values for the character.
The real answer is - you wouldn't. Using bitfields in unions (or at all) like this is inherently unportable and may be undefined. If you need to fiddle with bits, you are much better off using the C++ bitwise operators.
Because the exercise demonstrates breaking up a value into bits using a bitfield and a union.
Assuming you know what a union is, if you were extracting something less repetitive from a binary value then you might want use it for clarity instead of making say two 24 bit integers from 48 chars out of shifts and masks.
But for the example in the task, shifts and masks would be much cleaner code, so you would probably not use a union for this task.
void disp_bits(unsigned b)
{ // not tested
for ( int shift = 7; shift >= 0; --shift )
cout << ( ( b >> shift ) & 1 ) << ' ';
cout << "\n";
}
Unions are used in network protocols. They can also be handy to fake out polymorphism in C. Generally they are a special use case.
In this example, it is sort of a dummy example to show you a little code.
Related
I'm learning C++ and this is my code:
int val1,val2;
char op;
cout << "Please enter a calculation (operand operator operand):";
cin >> val1 >> op >> val2;
if((val1<0||val1>9)||(val2<0||val2>9)) {
cout << "Operand must be between 0 and 10!" << endl;
}
cout << "val1: " << val1 << " val2: " << val2 << endl;
The validation works but I still haven't just one digit in the variable val1 or val2 if I enter for example 34+56.
I want to end up with an error message for a number that has 2 digits or more and I want to have only one digit in the variables val1 and val2.
I tried working with chars, strings and isdigit() but I'm still in the dark here. Thx for the help!!
#include <iostream>
#include <string>
int main(){
int x = 100;
std::cout << std::to_string(x)[0] - '0';
}
okay that's fine. first digit in the number. I have c++11 solution.
while compiling add compiler flag -std=c++11
First, I'd like to suggest getting your input separately because it will greatly reduce the complexity of your code.
The problem you're facing is that all your inputs are treated at once when writing 34+56 and treated 3 times when read separately like in 34 + 56 (because of the space).
Therefore, what you need to do is read the whole line:
std::cout << "Please enter a calculation:";
std::string str;
std::getline (std::cin, str);
Then, you need to locate the sign and split your string there:
// "34+56"
std::size_t index = str.find_first_of("+-/*"); // returns the index 2
std::string operand1 = str.substr(0, index); // "34"
std::string operand2 = str.substr(index + 1); // "56"
Finally, you can output an
Error message for a number that has 2 digits or more and have only one digit in the variables val1 and val2.
// converts string -> int
int val1 = atoi(operand1.c_str());
int val2 = atoi(operand1.c_str());
// check if in range
if( (val1<0||val1>9) || (val2<0||val2>9) ) {
std::cout << "Operand must be between 0 and 10!" << std::endl;
std::cout << "Using first digit of operands..." << std::endl;
//Edit(wrong operation): Use the leftmost character minus character '0'
val1 = operand1[0] - '0';
val2 = operand2[0] - '0';
}
Notes: I did not actually test this. There are many cases where this will fail(i.e there is more than one operation). You could also argue that finding the first valid character and saving it is more efficient, but I find extracting the whole operands into strings cleaner.
Solved it like this:
while(true) {
cout << "Please enter a calculation (operand operator operand):" << endl;
while(true) {
cin >> val1 >> op >> val2;
if((val1<0||val1>9)||(val2<0||val2>9)) {
cout << "Wrong input! Try again." << endl;
break;
}
cout << "val1: " << val1 << " val2: " << val2 << endl;
}
}
Seems like the most obvious solution. Thxalot!!
I am trying to replace color in bmp image. I tried making unsigned char variable directly equal to some value... like
unsigned char oldr=255, oldg=255, oldb=0
This works pretty fine.
But now I want to take that color as input from the user.
When I use cin stream, it takes 255 as three characters, so directly getting input to unsigned char is not working.
I tried to take input to integer and then typecast to char...
But that is not working. I tried to print the characters and that characters, sometimes, are fine with respect to ASCII table. and sometimes only show spaces. But don't work in bitmap.
unsigned int inewr, inewg, inewb, ioldr, ioldg, ioldb // Creating Integers;
cout << "Enter R - G - B of Color to Replace: ";
cin >> ioldr >> ioldg >> ioldb; // Taking Integers of Old Color From User
cout << "Enter R - G - B of New: ";
cin >> inewr >> inewg >> inewb; // Taking Integers of New Color From User
// Type casting to char
unsigned char newr=inewr, newg=inewg, newb=inewb, oldr=ioldr, oldg=ioldr, oldb=ioldb;
cout << newr << " " << newg << " " << newb << endl; // Printing out characters
cout << oldr << " " << oldg << " " << oldb << endl;`
And then Checking color and writing in file...
for (int j=0; j<height; j++) {
for (int i=0; i<width*3; i+=3) {
b = mainarray[i][j];
g = mainarray[i+1][j];
r = mainarray[i+2][j];
if ( r==oldr && g==oldg && b==oldb) {
fout.write((char*) &newb, 1);
fout.write((char*) &newg, 1);
fout.write((char*) &newr, 1);
} else {
fout.write((char*) &b, 1);
fout.write((char*) &g, 1);
fout.write((char*) &r, 1);
}
}
}
Note: Arrays and all other things are ok in the code that I didn't show you...
Just there is problem in type casting. As I said putting oldr=255 works very fine...
Also I am not using any library. It is for 24-bit bitmap images
You're mistaking issues with outputting characters for problems with inputting them. Simply cin >> my_unsigned_char works just fine: the user types 255 and that value is stored in my_unsigned_char. The apparent problem is in...
cout << newr << " " << newg << " " << newb << endl; // Printing out characters
When the values are unsigned_char this sees values like 255 and sends them to the terminal as individual characters, rather than displaying the numeric value as a series of characters representing the individual digits in decimal, i.e. '2', then '5', then '5'.
Summarily, you can input directly to unsigned char, but should then cast to (int) while outputting if you want to read the numeric value entered:
std::cout << static_cast<int>(my_unsigned_char) << '\n';
first: I see some error in the code:
there is missing ";" after ioldb
unsigned int inewr, inewg, inewb, ioldr, ioldg, ioldb // Creating Integers;
the "oldg=ioldr" must be "oldg=ioldg"
// Type casting to char
unsigned char newr=inewr, newg=inewg, newb=inewb, oldr=ioldr, oldg=ioldr, oldb=ioldb;
there is more "`" in the end.
cout << oldr << " " << oldg << " " << oldb << endl;`
if you you want to checke the value you cin, I think you need to cout as following, it's more clear:
cout << static_cast<unsigned int>(newr) << " " << static_cast<unsigned int>(newg) << " " << static_cast<unsigned int>(newb) << endl; // Printing out characters
cout << static_cast<unsigned int>(oldr) << " " << static_cast<unsigned int>(oldg) << " " << static_cast<unsigned int>(oldb) << endl;
And can you more detail about the fault about "don't work in bitmap", and I think the fout must be initialized by "std::ofstream::binary"
I'm writing a program that will take an 8 digit number as input by the user and will evaluate it so if any digit that appears more than 3 times will be labelled as "unacceptable"; if all digits appear 3 or fewer times it is labelled as "acceptable".
So these numbers:
41124535, 13134113, 24255411
would all be labelled as acceptable, but these ones
34233332, 31111412, 55551122
would be labelled as unacceptable.
My approach is if... else chains and nests. So far I've managed to make a chain work, but it can only compare the digits when they repeat up to 2 times. Then I have a nest, but it only works if I write the else part every step of the way, instead of just leaving one single else at the end. This is crucial since the else part in the end will take the algorithm to a new if else nest that will evaluate the rest of the 8 digit long number.
The beginning of the program:
cout << "\n\n\t Input 1st digit:";
cin >> A;
cout << "\t Input 2nd digit:";
cin >> B;
cout << "\t Input 3rd digit:";
cin >> C;
cout << "\t Input 4th digit:";
cin >> D;
cout << "\t Input 5th digit:";
cin >> E;
cout << "\t Input 6th digit:";
cin >> F;
cout << "\t Input 7th digit:";
cin >> G;
cout << "\t Input 8th digit:";
cin >> H;
cout << "\n\t The number is: [";
cout << A;
cout << B;
cout << C;
cout << D;
cout << E;
cout << F;
cout << G;
cout << H;
cout << "]";
the if...else chain:
if (A==B)
cout << " Unacceptable!";
else
if (B==C)
cout << " Unacceptable!";
else
if (C==D)
cout << " Unacceptable!";
else
if (D==E)
cout << " Unacceptable!";
else
if (E==F)
cout << " Unacceptable!";
else
if (F==G)
cout << " Unacceptable!";
else
if (G==H)
cout << " Unacceptable!";
else
cout << " Acceptable";
then the nest with several else commands:
if (A==B)
{
if (A==C)
{
if (A==D)
cout << " Unacceptable!";
else
cout << " Acceptable";
}
else
cout << " Acceptable";
}
else
cout << " Acceptable";
so my guess is an if...else chain with if...else nests for each variable, but I can't work it out.
I'm not sure if you are using nested if statements for a specific reason - challenge, etc.? I'll assume you're not.
You can read the digits as one string - you could read as an int, but then you have to extract the digits from that anyways.
std::string input;
std::cin >> input;
/* validate input, make sure that it's 8 digits,
* that they are all digits, etc. - hint: int isdigit(int c)
*/
You can use a std::map to keep a histogram of the digits.
std::map< char, int > digit_histogram;
for (auto ch : input)
digit_histogram[ch]++;
Then the count of any digit dig is available as digit_histogram[dig]. You can loop through the map, or loop from 0-9 and discard any that is > 3.
This works for any number of digits, and it's 5 lines long without error checking. The point of programming is to make the computer do the work for you ;)
Start with some tests. This helps you understand your requirements, and clarifies your interface and how the function will be called. As this isn't a tutorial on unit testing, I'll just write a simple program that checks all the test cases succeed:
#include <cstdlib>
int main()
{
// these should all return true
if (!validate("41124535")) return EXIT_FAILURE;
if (!validate("13134113")) return EXIT_FAILURE;
if (!validate("24255411")) return EXIT_FAILURE;
// these should all return false
if (validate("34233332")) return EXIT_FAILURE;
if (validate("31111412")) return EXIT_FAILURE;
if (validate("55551122")) return EXIT_FAILURE;
return EXIT_SUCCESS;
}
Obviously this won't compile, as you haven't declared validate(). So let's add it, before main():
#include <string>
bool validate(const std::string& s)
{
return true;
}
It now compiles, but of course it fails because it never returns false. Now we can code the solution. We can count the occurrences of each character with a std::map:
#include <map>
#include <string>
static const int max_repeats = 3;
bool validate(const std::string& s)
{
std::map<char,int> counts;
for (char c: s)
if (++counts[c] > max_repeats)
return false;
return true;
}
Now, this runs, but it fails on the second test (found by commenting out this test and observing a pass - a real unit-test framework would identify the failing test for you).
The failing test has four 1s in it, so it fails. Why was it suppose to succeed? Ah, perhaps we've misinterpreted the requirement! Perhaps it's intended that the string have no more than three consecutive identical characters? Well we can do that too, by keeping count of the most recently seen character and how many repeats.
#include <string>
static const int max_repeats = 3;
bool validate(const std::string& s)
{
char last_seen = 0;
int repeats = 0;
for (char c: s) {
if (c != last_seen) {
// reset the matcher
last_seen = c;
repeats = 1;
} else {
// have we seen too many?
if (++repeats > max_repeats)
return false;
}
}
return true;
}
There are a few things to clean up, such as test cases with exactly three consecutive identical characters, and (perhaps) you might want to validate the length of the argument string.
And you can then convert it into a full program:
#include <iostream>
int main(int argc, char **argv)
{
while (*++argv)
std::cout << *argv << (validate(*argv) ? " OK" : " FAIL") << std::endl;
}
Here's my program for bit representation of characters. But I don't know does it show me right or wrong representation? There are suspicious units (red colored).
Can you explain me what's this (if it's right) or what's wrong with my code if these units should not be. Thanks
#include "stdafx.h"
#include "iostream"
using namespace std;
struct byte {
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
unsigned int d:1;
unsigned int e:1;
unsigned int f:1;
unsigned int g:1;
unsigned int h:1;
};
union SYMBOL {
char letter;
struct byte bitfields;
};
int main() {
union SYMBOL ch;
cout << "Enter your char: ";
while(true) {
ch.letter = getchar();
if(ch.letter == '\n') break;
cout << "You typed: " << ch.letter << endl;
cout << "Bite form = ";
cout << ch.bitfields.h;
cout << ch.bitfields.g;
cout << ch.bitfields.f;
cout << ch.bitfields.e;
cout << ch.bitfields.d;
cout << ch.bitfields.c;
cout << ch.bitfields.b;
cout << ch.bitfields.a;
cout << endl << endl;
}
}
See the ASCII table to understand the output you're getting:
a has the decimal value of 97, and 97 is 01100001 in binary
b has the decimal value of 98, and 97 is 01100010 in binary
and so on.
Bit fields are not portable. The biggest problem is that you don't know in which order the bits will be assigned to the individual bit fields, but you don't even know actually whether the struct will have 1, 2 or any other number of bytes.
I'd recommend using unsigned char (because you don't know whether char is signed or unsigned), and using code like (ch & 0x80) != 0, (ch & 0x40) != 0 etc.
So I have this program:
#include <iostream>
using namespace std;
bool prime(int input)
{
// cout << "pinput: " << input << endl;
int i = ((input/2) + 1);
// cout << "pi: " << i << endl;
int c;
for (i>0; i--;){
//cout << "pi: " << i << endl;
if (input == 3 || input == 2){
// cout << "true" << endl;
return true;
}
if (input == 1){
// cout << "pi = 1" << endl;
return false;
}
c= input%i;
if (c==0 || i == 1 ){
// cout << "false" << endl;
return false;
}
else if (c!=0 && i<4){
// cout << "true" << endl;
return true;
}
}
return 0;
}
int factor(int input){
// cout << "finput: " << input << endl;
int i = (input/2) + 1;
int c;
int e;
bool d = false;
for (i>0; i--;){
// cout << "fi: " << i << endl;
c = input%i;
if (c==0){
d = prime(i);
if (d==true){
// cout << "found" << endl;
return i;}
}
if (i==1){
// cout << "fi = 1";
return 0;
}
//cout << "not prime" << endl;
}
return 0;
}
int main(){
int woot;
cout << "Please insert quater: " <<endl;
cin >> woot;
int answer;
answer = factor(woot);
if (answer == 0)
cout << "no prime factors" << endl;
else
cout << "answer is: " <<answer << endl;
return 0;
}
It seems to work until I put a really big number in like more specifically the number 600851475143, in which case I always get different answers when I run that number now I'm pretty sure it's just exceeding the size of it's variable type. Now then I was looking and I can't find the right variable type for a number that big, I int and long seem to be for numbers that are for numbers up to 4294967295 if unsigned however that is only 10 digits long, mine is 12. What type of variable should I use? Or will that even fix the problem? The program is to find the largest prime factor of a number (Euler problem 3). Any tips links or advice would be appreciated. And of course an answer extra appreciated! :D
Interesting typo alert!
This is unlikely to be doing what you think it is doing...
for (i>0; i--;){
While it is perfectly legal syntax, and will loop the correct number of times, the value of i inside the loop is (probably) going to be one less than you intended...
% cat 4237157.c++
#include <iostream>
int main()
{
{
std::cout << "Your loop: " << std::endl;
int i = 10;
for (i>0; i--;)
{
std::cout << i << std::endl;
}
}
{
std::cout << "More conventionally: " << std::endl;
for (int i = 10; i > 0; i--)
{
std::cout << i << std::endl;
}
}
return EXIT_SUCCESS;
}
% g++ -o 4237157{,.c++}
% ./4237157
Your loop:
9
8
7
6
5
4
3
2
1
0
More conventionally:
10
9
8
7
6
5
4
3
2
1
The syntax for a for-loop in C-like languages is:
for (variable initialization; conditional; variable increment)
You are evaluating "i>0" instead of doing any initalization. This may as well be blank. Then you are evaluating whether i-- is zero. Since i is post-decremented, your loop starts with i being one less than it was initialized with before the loop, executes until (and including) being equal to zero and then terminates.
A lot of the problems on Project Euler call for arbitrary-precision arithmetic, which isn't covered by the C++ standard library.
Have a look at the C++ Big Integer Library.
If you want arbitarily big numbers, you need an arbitary precision arithmetic library
unsigned long 4294967295
unsigned long long 18446744073709551615
unsigned long long is not standard C++, but most compilers support it as an extension. The maximum should be at least 2^64 - 1, which is more than enough.
If you later want even larger numbers, you can use a arbitrary precision library such as GMP. They have a C++ interface.