why I am getting output blank? pointers are able to modify but can't read.why?
#include <iostream>
using namespace std;
int main(){
int a = 0;
char *x1,*x2,*x3,*x4;
x1 = (char *)&a;
x2 = x1;x2++;
x3 = x2;x3++;
x4 = x3;x4++;
*x1=1;
*x2=1;
*x3=1;
*x4=1;
cout <<"#" << *x1 << " " << *x2 << " " << *x3 << " " << *x4 << "#"<<endl ;
cout << a << endl;
}
[Desktop]👉 g++ test_pointer.cpp
[Desktop]👉 ./a.out
# #
16843009
I want to read the value of integer by using pointers type of char.
so i can read byte by byte.
You're streaming chars. These get automatically ASCII-ised for you by IOStreams*, so you're seeing (or rather, not seeing) unprintable characters (in fact, all 0x01 bytes).
You can cast to int to see the numerical value, and perhaps add std::hex for a conventional view.
Example:
#include <iostream>
#include <iomanip>
int main()
{
int a = 0;
// Alias the first four bytes of `a` using `char*`
char* x1 = (char*)&a;
char* x2 = x1 + 1;
char* x3 = x1 + 2;
char* x4 = x1 + 3;
*x1 = 1;
*x2 = 1;
*x3 = 1;
*x4 = 1;
std::cout << std::hex << std::setfill('0');
std::cout << '#' << std::setw(2) << "0x" << (int)*x1
<< ' ' << std::setw(2) << "0x" << (int)*x2
<< ' ' << std::setw(2) << "0x" << (int)*x3
<< ' ' << std::setw(2) << "0x" << (int)*x4
<< '#' << '\n';
std::cout << "0x" << a << '\n';
}
// Output:
// #0x01 0x01 0x01 0x01#
// 0x1010101
(live demo)
Those saying that your program has undefined are incorrect (assuming your int has at least four bytes in it); aliasing objects via char* is specifically permitted.
The 16843009 output is correct; that's equal to 0x01010101 which you'd again see if you put your stream into hex mode.
N.B. Some people will recommend reinterpret_cast<char*>(&a) and static_cast<int>(*x1), instead of C-style casts, though personally I find them ugly and unnecessary in this particular case. For the output you can at least write +*x1 to get a "free" promotion to int (via the unary + operator), but that's not terribly self-documenting.
* Technically it's something like the opposite; IOStreams usually automatically converts your numbers and booleans and things into the right ASCII characters to appear correct on screen. For char it skips that step, assuming that you're already providing the ASCII value you want.
Assuming an int is at least 4 bytes long on your system, the program manipulates the 4 bytes of int a.
The result 16843009 is the decimal value of 0x01010101, so this is as you might expect.
You don't see anything in the first line of output because you write 4 characters of a binary value 1 (or 0x01) which are invisible characters (ASCII SOH).
When you modify your program like this
*x1='1';
*x2='3';
*x3='5';
*x4='7';
you will see output with the expected characters
#1 3 5 7#
926233393
The value 926233393 is the decimal representation of 0x37353331 where 0x37 is the ASCII value of the character '7' etc.
(These results are valid for a little-endian architecture.)
You can use unary + for converting character type (printed as symbol) into integer type (printed as number):
cout <<"#" << +*x1 << " " << +*x2 << " " << +*x3 << " " << +*x4 << "#"<<endl ;
See integral promotion:
Have a look at your declarations of the x's
char *x1,*x2,*x3,*x4;
these are pointers to chars (characters).
In your stream output they are interpreted as printable characters.
A short look into the ascii-Table let you see that the lower numbers are not printeable.
Since your int a is zero also the x's that point to the individual bytes are zero.
One possibility to get readeable output would be to cast the characters to int, so that the stream would print the numerical representation instead the ascii character:
cout <<"#" << int(*x1) << " " << int(*x2) << " " << int(*x3) << " " << int(*x4) << "#"<<endl ;
If I understood your problem correctly, this is the solution
#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
int a = 0;
char *x1,*x2,*x3,*x4;
x1 = (char*)&a;
x2 = x1;x2++;
x3 = x2;x3++;
x4 = x3;x4++;
*x1=1;
*x2=1;
*x3=1;
*x4=1;
cout <<"#" << (int)*x1 << " " << (int)*x2 << " " << (int)*x3 << " " << (int)*x4 << "#"<<endl ;
cout << a << endl;
}
I have a 24-bit array:
uint32_t rgbdata[] = { 0x00ff00 0xff0000 0x0000ff ...... }
Let's say the above data is in RGB order and I want GRB order
uint32_t grbdata[] = { 0xff0000 0x00ff00 0x0000ff ...... }
Without using loops, is there a quick endian manipulation way to do a certain byte order? Speed is of utmost importance in this case.
Here is a partial example of a uint24_t that you might port to your tools (I don't know the 'current' arduino's tool set)
// Note: compile with -std=c++17 for the using comma list
// or remove these and put the "std::" into code
#include <algorithm>
using std::swap;
#include <iostream>
using std::cout, std::cerr, std::endl, std::hex, std::dec, std::cin; // c++17
#include <string>
using std::string, std::to_string; // c++17
#include <sstream>
using std::stringstream;
class Uint24_t
{
public:
Uint24_t() : data {0,0,0}
{
cout << "\n sizeof(Uint24_t)= " << sizeof(Uint24_t) // reports 3 bytes
<< " bytes, * 8= " << (sizeof(Uint24_t) * 8) << " bits." << endl;
}
Uint24_t(uint32_t initVal) : data {0,0,0}
{
data[0] = static_cast<uint8_t>((initVal >> 0) & 0xff); // lsbyte
data[1] = static_cast<uint8_t>((initVal >> 8) & 0xff); //
data[2] = static_cast<uint8_t>((initVal >> 16) & 0xff); // msbyte
cout << "\n sizeof(Uint24_t)= " << sizeof(Uint24_t) // reports 3 bytes
<< " bytes, * 8= " << (sizeof(Uint24_t) * 8) << " bits." << endl;
}
~Uint24_t() = default;
std::string show() {
stringstream ss;
ss << " show(): "
<< static_cast<char>(data[2]) << "."
<< static_cast<char>(data[1]) << "."
<< static_cast<char>(data[0]);
return ss.str();
}
std::string dump() {
stringstream ss;
ss << " dump(): " << hex
<< static_cast<int>(data[2]) << "."
<< static_cast<int>(data[1]) << "."
<< static_cast<int>(data[0]);
return ss.str();
}
void swap0_2() { swap(data[0], data[2]); }
private:
uint8_t data[3]; // 3 uint8_t 's
};
class T976_t // ctor and dtor compiler provided defaults
{
public:
int operator()() { return exec(); } // functor entry
private: // methods
int exec()
{
Uint24_t u24(('c' << 16) + // msbyte
('b' << 8) +
('a' << 0));
cout << "\n sizeof(u24) = " << sizeof(u24) << " bytes"
<< "\n " << u24.show()
<< "\n " << u24.dump() << std::endl;
u24.swap0_2(); // swapping lsByte and msByte
cout << "\n sizeof(u24) = " << sizeof(u24) << " bytes"
<< "\n " << u24.show()
<< "\n " << u24.dump() << std::endl;
return 0;
}
}; // class T976_t
int main(int , char**) { return T976_t()(); } // call functor
Typical output:
sizeof(Uint24_t)= 3 bytes, * 8= 24 bits.
sizeof(u24) = 3 bytes
show(): c.b.a
dump(): 63.62.61
sizeof(u24) = 3 bytes
show(): a.b.c
dump(): 61.62.63
I have a char [], with the buffer name, the data is saved using an ifstream in binary mode,
void File::mostrarBuffer(){
for (int a = 0; a < std::strlen(buffer); a++){
std::cout << std::hex << ((int)buffer[a]) << std::endl;
}
// para ver char test, only for test
std::cout << "===" << std::endl;
for (int a = 0; a < std::strlen(buffer); a++){
std::cout << buffer[a] << std::endl;
}
char charTest = '\211';
std::cout << "===" << std::endl;
std::cout << std::hex << (int)charTest << std::endl;
std::cout << std::hex << (int)buffer[0] << std::endl;
}
the shell out:
ffffff89
50
4e
47
===
\211
P
N
G
===
ffffff89
ffffff89
the file in hexdump ("little-endian"):
0000000 5089 474e 0a0d 0a1a 0000 0d00 4849 5244
my question is why, appears ffffff89 and not 89, and only on the first element of char [] I've been around with this and can not find the solution. thanks for reading.
this solution works for me:
std::cout << std::hex << ((unsigned int)(unsigned char)buffer[a])
<< std::endl;
Because your chars are signed (highest bit is set).
I'm sorry, I'm not familiar with using std::hex but you somehow need to treat it like an unsigned char value. Try casting the char to and unsigned type.
I'm not sure, but I think I remember there being something in Java that can specify how far from the left of a window that a string or digit begins..
How to easily format a table?
I have this (using setw):
Bob Doe 10.96 7.61 14.39 2.11 47.30 14.21 44.58 5.00 60.23
Helen City 10.44 7.78 16.27 1.99 48.92 13.93 53.79 5.00 70.97
Joe Green 10.90 7.33 14.49 2.05 47.91 14.15 44.45 4.70 73.98
and ideally would like:
Bob Doe BLR 10.96 7.61 14.39 2.11 47.30 14.21 44.58 5.00 60.23 4:27.47
Helen City CUB 10.90 7.33 14.49 2.05 47.91 14.15 44.45 4.70 73.98 4:29.17
Joe Green USA 10.44 7.78 16.27 1.99 48.92 13.93 53.79 5.00 70.97 5:06.59
Is the only way calculations? Or is there some magical even more simple way?
In C++, you have three functions to help you do what you want. There are defined in <iomanip>.
- setw() helps you defined the width of the output.
- setfill() Fill the rest with the character you want (in your case ' ').
- left (or right) allow you to define the alignment.
Here is the code to write your first line :
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
const char separator = ' ';
const int nameWidth = 6;
const int numWidth = 8;
cout << left << setw(nameWidth) << setfill(separator) << "Bob";
cout << left << setw(nameWidth) << setfill(separator) << "Doe";
cout << left << setw(numWidth) << setfill(separator) << 10.96;
cout << left << setw(numWidth) << setfill(separator) << 7.61;
cout << left << setw(numWidth) << setfill(separator) << 14.39;
cout << left << setw(numWidth) << setfill(separator) << 2.11;
cout << left << setw(numWidth) << setfill(separator) << 47.30;
cout << left << setw(numWidth) << setfill(separator) << 14.21;
cout << left << setw(numWidth) << setfill(separator) << 44.58;
cout << left << setw(numWidth) << setfill(separator) << 5.00;
cout << left << setw(numWidth) << setfill(separator) << 60.23;
cout << endl;
cin.get();
}
EDIT :
To reduce the code, you can use a template function :
template<typename T> void printElement(T t, const int& width)
{
cout << left << setw(width) << setfill(separator) << t;
}
That you can use like this :
printElement("Bob", nameWidth);
printElement("Doe", nameWidth);
printElement(10.96, numWidth);
printElement(17.61, numWidth);
printElement(14.39, numWidth);
printElement(2.11, numWidth);
printElement(47.30, numWidth);
printElement(14.21, numWidth);
printElement(44.58, numWidth);
printElement(5.00, numWidth);
printElement(60.23, numWidth);
cout << endl;
Here are the various functions I use to display data in an organized, tabular form, along with an example demonstrating a possible use scenario.
Because the functions use stringstreams, they aren't as fast as other solutions, but for me that never matters --- the computing bottlekneck is elsewhere.
One advantage of using stringstreams is that the functions alter the precision of their own (internal scope) stringstreams, instead of changing the static cout precision. So you never have to worry about unintentionally modifying precision in a way that persists to affect other parts of your code.
DISPLAYING ARBITRARY PRECISION
This prd function (short for "print double") simply prints a double value with a specified precision.
/* Convert double to string with specified number of places after the decimal. */
std::string prd(const double x, const int decDigits) {
stringstream ss;
ss << fixed;
ss.precision(decDigits); // set # places after decimal
ss << x;
return ss.str();
}
The following is just a variant that allows you to specify a blank-space padding to the left of the number. This can be helpful in displaying tables.
/* Convert double to string with specified number of places after the decimal
and left padding. */
std::string prd(const double x, const int decDigits, const int width) {
stringstream ss;
ss << fixed << right;
ss.fill(' '); // fill space around displayed #
ss.width(width); // set width around displayed #
ss.precision(decDigits); // set # places after decimal
ss << x;
return ss.str();
}
CENTER-ALIGN FUNCTION
This function simply center-aligns text, padding left and right with blank spaces until the returned string is as large as the specified width.
/*! Center-aligns string within a field of width w. Pads with blank spaces
to enforce alignment. */
std::string center(const string s, const int w) {
stringstream ss, spaces;
int padding = w - s.size(); // count excess room to pad
for(int i=0; i<padding/2; ++i)
spaces << " ";
ss << spaces.str() << s << spaces.str(); // format with padding
if(padding>0 && padding%2!=0) // if odd #, add 1 space
ss << " ";
return ss.str();
}
EXAMPLE OF TABULAR OUTPUT
So, we could use the prd and center functions above to output a table in the following fashion.
The code:
std::cout << center("x",10) << " | "
<< center("x^2",10) << " | "
<< center("(x^2)/8",10) << "\n";
std::cout << std::string(10*3 + 2*3, '-') << "\n";
for(double x=1.5; x<200; x +=x*2) {
std::cout << prd(x,1,10) << " | "
<< prd(x*x,2,10) << " | "
<< prd(x*x/8.0,4,10) << "\n";
}
will print the table:
x | x^2 | (x^2)/8
------------------------------------
1.5 | 2.25 | 0.2812
4.5 | 20.25 | 2.5312
13.5 | 182.25 | 22.7812
40.5 | 1640.25 | 205.0312
121.5 | 14762.25 | 1845.2812
RIGHT- and LEFT-ALIGN FUNCTIONS
And, of course, you can easily construct variants of the center function that right- or left-align and add padding spaces to fill the desired width. Here are such functions:
/* Right-aligns string within a field of width w. Pads with blank spaces
to enforce alignment. */
string right(const string s, const int w) {
stringstream ss, spaces;
int padding = w - s.size(); // count excess room to pad
for(int i=0; i<padding; ++i)
spaces << " ";
ss << spaces.str() << s; // format with padding
return ss.str();
}
/*! Left-aligns string within a field of width w. Pads with blank spaces
to enforce alignment. */
string left(const string s, const int w) {
stringstream ss, spaces;
int padding = w - s.size(); // count excess room to pad
for(int i=0; i<padding; ++i)
spaces << " ";
ss << s << spaces.str(); // format with padding
return ss.str();
}
I'm sure there are plenty of more-elegant ways to do this kind of thing --- certainly there are more concise ways. But this is what I do. Works well for me.
Just use sprintf with format specifiers to format fields. You can also use MFC CString
#include <iostream>
#include "stdio.h"
using namespace std;
int main()
{
char buf[256];
char pattern[] = "%10s %10s %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f";
sprintf(buf, pattern, "Bob", "Doe", 10.96, 7.61, 14.39, 2.11, 47.30, 14.21, 44.58, 5.00, 60.23);
cout << buf << endl;
sprintf(buf, pattern, "Helen", "City", 10.44, 7.78, 16.27, 1.99, 48.92, 13.93, 53.79, 5.00, 70.97);
cout << buf << endl;
sprintf(buf, pattern, "Joe", "Green", 10.90, 7.33, 14.49, 2.05, 47.91, 14.15, 44.45, 4.70, 73.98);
cout << buf << endl;
}
You could do something like this to simplify the process a bit.
#include <iomanip>
#include <iostream>
struct TableFormat {
int width;
char fill;
TableFormat(): width(14), fill(' ') {}
template<typename T>
TableFormat& operator<<(const T& data) {
std::cout << data << std::setw(width) << std::setfill(fill);
return *this;
}
TableFormat& operator<<(std::ostream&(*out)(std::ostream&)) {
std::cout << out;
return *this;
}
};
int main() {
TableFormat out;
out << "Bob" << "Doe";
out.width = 8;
out << "BLR" << 10.96 << 7.61 << 14.39 << 2.11 << 47.30;
}
Which would print out (horribly in my case, but it's "customisable" to a degree):
Bob Doe BLR 10.96 7.61 14.39 2.11 47.3
The code is pretty self-explanatory, it's just a wrapper around std::cout to allow you to make the tedious calls easier, the second overload for operator<< is to allow you send std::endl..
C++20 includes <format> but it's not supported by libc++ for now.
I suggest to use {fmt} library since it could be obtained easily in Ubuntu20.
According to the doc, you may specify the width as an argument as well.
Format example: {2:<{0}}
`2` -> Use second arg as value.\
`:` -> Use non-default format.\
`<` -> Align to left\
`{0}` -> Use argument 0 as width.
Live Demo
#include <string>
#include <iostream>
#include <fmt/core.h>
#include <tuple>
#include <vector>
int main()
{
using Row = std::tuple<std::string, std::string, double>;
std::vector<Row> table = {
std::make_tuple("Bob", "Doe", 10.96),
std::make_tuple("Helen", "City", 10.44),
std::make_tuple("Joe", "Green", 10.90)
};
size_t nameWidth{12};
size_t valWidth{7};
for(const auto& row: table){
std::cout << fmt::format("{2:<{0}} {3:<{0}} {4:<{1}} \n",
nameWidth, valWidth, std::get<0>(row), std::get<1>(row), std::get<2>(row) );
}
}
Output
Bob Doe 10.96
Helen City 10.44
Joe Green 10.9
Assuming you want to format your output to resemble a table, what you need is I/O manipulators.
You can use setw() manipulator to set the output width and setfill() to set the filling character.
Considering an example:
string firstname = "Bob";
string lastname = "Doe";
string country = "BLR";
float f1 = 10.96f, f2=7.61f, f3=14.39f, f4=2.11f, f5=47.30f, f6=14.21f, f7=44.58f, f8=5.00f, f9=60.23f;
string time = "4:27.47";
cout << setw(12) << firstname << set(12) << lastname;
cout << setw(5) << country << setprecision(2) << f1 << setprecision(2) << f2 << setprecision(2) << f3..
use setw() to set the width while printing a string
use setprecision to set the precision for floating values
read MSDN
I'm not sure what you wrote so I can't see what's wrong, but you can get the results you want with std::setw:
#include <iostream>
#include <iomanip>
int main() {
std::cout << std::left << std::setw(20) << "BoB" << std::setw(20) << 123.456789 << '\n';
std::cout << std::left << std::setw(20) << "Richard" << std::setw(20) << 1.0 << '\n';
}
http://ideone.com/Iz5RXr
Is there a way to make setw and setfill pad the end of a string instead of the front?
I have a situation where I'm printing something like this.
CONSTANT TEXT variablesizeName1 .....:number1
CONSTANT TEXT varsizeName2 ..........:number2
I want to add a variable amount of '.' to the end of
"CONSTANT TEXT variablesizeName#" so I can make ":number#" line up on the screen.
Note: I have an array of "variablesizeName#" so I know the widest case.
Or
Should I do it manually by setting setw like this
for( int x= 0; x < ARRAYSIZE; x++)
{
string temp = string("CONSTANT TEXT ")+variabletext[x];
cout << temp;
cout << setw(MAXWIDTH - temp.length) << setfill('.') <<":";
cout << Number<<"\n";
}
I guess this would do the job but it feels kind of clunky.
Ideas?
You can use manipulators std::left, std::right, and std::internal to choose where the fill characters go.
For your specific case, something like this could do:
#include <iostream>
#include <iomanip>
#include <string>
const char* C_TEXT = "Constant text ";
const size_t MAXWIDTH = 10;
void print(const std::string& var_text, int num)
{
std::cout << C_TEXT
// align output to left, fill goes to right
<< std::left << std::setw(MAXWIDTH) << std::setfill('.')
<< var_text << ": " << num << '\n';
}
int main()
{
print("1234567890", 42);
print("12345", 101);
}
Output:
Constant text 1234567890: 42
Constant text 12345.....: 101
EDIT:
As mentioned in the link, std::internal works only with integer, floating point and monetary output. For example with negative integers, it'll insert fill characters between negative sign and left-most digit.
This:
int32_t i = -1;
std::cout << std::internal
<< std::setfill('0')
<< std::setw(11) // max 10 digits + negative sign
<< i << '\n';
i = -123;
std::cout << std::internal
<< std::setfill('0')
<< std::setw(11)
<< i;
will output
-0000000001
-0000000123
Something like:
cout << left << setw(MAXWIDTH) << setfill('.') << temp << ':' << Number << endl;
Produces something like:
derp..........................:234
herpderpborp..................:12345678
#include <iostream>
#include <iomanip>
int main()
{
std::cout
<< std::setiosflags(std::ios::left) // left align this section
<< std::setw(30) // within a max of 30 characters
<< std::setfill('.') // fill with .
<< "Hello World!"
<< "\n";
}
//Output:
Hello World!..................