I have tried to simplify the original code to a simple test example which replicates the issue that I am having. I do apologize for the simple question in advance.. I am a beginner with C++.
So moving on the actual question.. why do I get 0 as an output? For the purposes of my this example and for my understanding, functions should not be modified with the exception of the numerical values in them should it be required (meaning I got it wrong:).
Many thanks in advance.
static unsigned short buffer[5];
void settingMemory()
{
memset(buffer, 0, sizeof(buffer));
}
void copingMemory(const unsigned short *pixels)
{
memcpy(&buffer[5], pixels, 5*sizeof(unsigned short));
}
void printingMemory()
{
unsigned short *test = buffer;
std::cout << *test << std::endl;
std::cout << *test++ << std::endl;
std::cout << *test++ << std::endl;
std::cout << *test++ << std::endl;
std::cout << *test++ << std::endl;
std::cout << *test++ << std::endl;
}
int main(int argc, char* argv[])
{
settingMemory();
unsigned short test[5];
test[0] = 5;
test[1] = 55;
test[2] = 555;
test[3] = 5555;
test[4] = 55555;
copingMemory(test);
printingMemory();
}
My output is:
0
0
0
0
0
0
The line memcpy(&buffer[5], pixels, 5*sizeof(unsigned short)); copies to the start of the 6th element of buffer (i.e. the first element /outside/ the buffer. Replace it with memcpy(&buffer[0], pixels, 5*sizeof(unsigned short));, so you copy it to the 1st element instead.
Related
I have a 64 bit unsigned integer and for some reason I have to store it inside a string. What I am wondering is that the value inside the string is same even after using the swapped integer?
For example:
#include <iostream>
#include <byteswap.h>
using namespace std;
int main()
{
uint64_t foo = 98;
uint64_t foo_reversed = bswap_64(foo);
std::string out = "";
out.append(reinterpret_cast<const char*>(&foo), sizeof(foo));
std::string out_reversed = "";
out_reversed.append(reinterpret_cast<const char*>(&foo_reversed), sizeof(foo_reversed));
std::cout << "out: " << out << std::endl;
std::cout << "out_reversed: " << out_reversed << std::endl;
return 0;
}
The string out and out_reversed have the exact same value, but I expect it to be different as the underlying integer foo and foo_reversed are swapped value of each other.
What am I missing here? Pardon me if it is a trivial mistake, but putting it out here on the chance that I'm missing some concept.
The output I see:
out: b
out_reversed: b
I was not expecting the above value for out_reversed
You can see the same thing with arrays of char:
int main()
{
char foo[8] = { 98, 0, 0, 0, 0, 0, 0, 0 };
char foo_reversed[8] = { 0, 0, 0, 0, 0, 0, 0, 98 };
std::string out(foo, 8);
std::string out_reversed(foo_reversed, 8);
std::cout << "out: " << out << std::endl;
std::cout << "out_reversed: " << out_reversed << std::endl;
return 0;
}
The chars with value 0 aren't printable, so the terminal doesn't display them
Here's an alternative printing.
The conversion you're trying to do is not just converting the QByteArray data to an int.
For example, assuming that QByteArray a [3] contains [0] = 36, 1 = 23, and [2] = 12 data, use the b variable in the form of int b in the form b = 362312. I want to do it.
In order to use QByteArray data as int data, QByteArray variable is assigned to QString variable and cast to string variable.
And I tried to print out the string variable, but the strange unknown data is output.
I tried to cast a string using toInt () after confirming that the string is printed normally, but the string is printed as strange characters.
So I could not do toInt ().
I run a lot of tests and the code is messy.
The reason I didn't delete the comment was not to show that I've tried various things.
if (QCanBus::instance()->plugins().contains(QStringLiteral("socketcan"))) {
qWarning() << "plugin available";
}
QString errorString;
QCanBusDevice *device = QCanBus::instance()->createDevice(
QStringLiteral("socketcan"), QStringLiteral("vcan0"), &errorString);
if (!device) {
qWarning() << errorString;
} else {
device->connectDevice();
std::cout << "connected vcan0" << std::endl;
device->connect(device, &QCanBusDevice::framesReceived, [this, device]() {
QCanBusFrame frame = device->readFrame();
QString testV = frame.toString();
// int testI = testV.split(" ")[0].toInt();
QString qvSpeed = frame.payload();
// int a = frame.payload().length();
std::string text = testV.toUtf8().constData();
std::string vSpeed = qvSpeed.toLocal8Bit().constData();
//At that point the vVal values are being updated in real time.
//I want to pass the updated vVal to qml gui in real time.
// int vVal = static_cast<int>(frame.payload()[0]);
// for(int i = 0; i < frame.payload().length(); ++i)
// std::cout << std::hex << static_cast<int>(frame.payload()[i]);
// std::cout << std::endl;
// if(vVal)
// int tSpeed = static_cast<int>(frame.payload()[0]);
// std::stringstream stream;
// stream <<
testVal1 += 0;
// if(frame.frameId() == 001)
// testVal2 = static_cast<int>(frame.payload()[0]);
// testVal2 += 20;
// duration += 200;
// emit sendMessage(testVal1, testVal2);
std::cout << vSpeed << std::endl;
// if(frame.frameId() == 001)
// std::cout << testI << std::endl;
// std::cout << "--------------" << std::hex << static_cast<int>(frame.payload()[0]) << "----------------" << std::endl;
});
}
Finally, QByteArray a [3] = {32, 34, 12};
Assuming you have data, you want to use this like int b = 323412.
In order to do that, I thought it would convert to a string and then to an integer, but even strings are not normal output.
I'm also attaching the strange string that is currently printed out below.
enter image description here
Since QByteArray stores its data as char * you can just cast its internal data, for example:
#include <QCoreApplication>
#include <iostream>
#include <iomanip>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
uint32_t num = 1234;
std::cout << "original number:" << num << std::endl;
std::cout << "bytes: " << std::endl;
QByteArray arr(reinterpret_cast<char *>(&num), sizeof(uint32_t));
for(int i = 0;i < arr.size();i ++)
{
std::cout << " 0x" << std::hex << std::setfill('0') << std::setw(2) << (arr.at(i) & 0xFF) << std::endl;
}
uint32_t *num2 = reinterpret_cast<uint32_t *>(arr.data());
std::cout << "casted number :" << std::dec << *num2 << std::endl;
return a.exec();
}
But I would not recommend this 'C' approach since it is fraught with errors.
Btw, I've never seen CAN data converted to QString. Usually it just 8 bytes of data, you worth cast it to a data struct instead, for example:
struct Data
{
uint32_t value1;
uint32_t value2;
} inData, outData;
inData.value1 = 1234;
inData.value2 = 5678;
QByteArray arr(reinterpret_cast<char *>(&inData), sizeof(Data));
outData = *reinterpret_cast<Data *>(arr.data());
//memcpy(&outData, arr.data(), static_cast<size_t>(arr.size())); // or this
i have a problem with one assignment that i have. I have to read a .ts file, read the packets that are inside and extract header information from each packet.
I have created a struct Packet that will hold all the info of the header, and i also have a vector in which i will push_back each Packet.
The problem is that the for loop stops for some reason on the 163rd loop. If i loop until lets say i=160, then the code escapes ends the loop, but when i print the vector.size() i get a really huge number which doesn't make sense. i guess it should be an integer value as high as the pushed back number of Packets.Here is the code that i have so far:
int main() {
FILE *ts_file = NULL;
ts_file = fopen64("/home/ddd/Desktop/Assignment/Streams/ddd.ts", "rb");
if (ts_file == NULL){
cout << "No file detected on this path, try again" << endl; // prints !!!Hello World!!!
}
TS_Analyzer *ts_analyzer;
ts_analyzer->parse_file(ts_file);
cout << "Finished main" << endl;
return 0;
}
void TS_Analyzer::parse_file(FILE *ts_file){
cout << "Inside parser" << endl;
fseek(ts_file,0,SEEK_END);
long file_size = ftell(ts_file);
rewind (ts_file);
number_of_packets = file_size/PACKET_SIZE;
unsigned int current_header_add = 0;
unsigned int i=0;
for (unsigned int j=1; i<number_of_packets; j++)
{
i++;
unsigned char TS_raw_header[4];
cout << "current position " << int(current_header_add) << endl;
current_header_add = ftell(ts_file);
fread(&TS_raw_header, sizeof(TS_raw_header), 1, ts_file);
Packet current_packet;
current_packet.sync_byte = TS_raw_header[0];
current_packet.transport_error_indicator = (TS_raw_header[1] & 0x80) >> 7;
current_packet.payload_start_indicator = (TS_raw_header[1] & 0x40) >> 6;
current_packet.transport_priority = (TS_raw_header[1] & 0x20) >> 5;
current_packet.PID = ((TS_raw_header[1] & 31) << 8) | TS_raw_header[2];
current_packet.transport_scrambling_control = (TS_raw_header[3] & 0xC0);
current_packet.adaption_field_control = (TS_raw_header[3] & 0x30) >> 4;
current_packet.continuity_counter = (TS_raw_header[3] & 0xF);
stream_packets.push_back(current_packet);
//cout << hex << int(current_packet.PID) << endl;
//cout << dec << "continuity counter " << int(current_packet.continuity_counter) << endl;
cout << " i " << int(i) << endl;
fseek(ts_file, 184, SEEK_CUR);
}
cout << "##" << endl;
cout << stream_packets.size() << endl;
}
class TS_Analyzer: public Analyzer {
public:
TS_Analyzer();
~TS_Analyzer();
struct Packet {
unsigned char sync_byte;
unsigned char transport_error_indicator;
unsigned char payload_start_indicator;
unsigned char transport_priority;
unsigned int PID;
unsigned char transport_scrambling_control;
unsigned char adaption_field_control;
unsigned char continuity_counter;
};
std::vector<Packet>stream_packets;
int number_of_packets = 0;
void parse_file(FILE *);
};
Any ideas of why the vector push_back breaks the for loop and why i cannot get a correct vector size?
If I put this code through the clang compiler, I get an error on following code:
TS_Analyzer *ts_analyzer;
ts_analyzer->parse_file(ts_file);
>> variable 'ts_analyzer' is uninitialized when used here
I guess you are encountering undefined behavior: As ts_analyzer as ptr is any random value, the data in its members is also very random.
I'm actually surprised that this code runs at all without crashing, though you can always be lucky.
If you like to fix this, try avoiding pointers by creating the object at the stack:
TS_Analyzer ts_analyzer;
ts_analyzer.parse_file(ts_file);
or if you really need allocated memory, at least fill in the pointer:
auto ts_analyzer = std::make_unique<TS_Analyzer>();
ts_analyzer->parse_file(ts_file);
I have this array : BYTE set[6] = { 0xA8,0x12,0x84,0x03,0x00,0x00, } and i need to insert this value : "" int Value = 1200; "" ....on last 4 bytes. Practically to convert from int to hex and then to write inside the array...
Is this possible ?
I already have BitConverter::GetBytes function, but that's not enough.
Thank you,
To answer original quesion: sure you can.
As soon as your sizeof(int) == 4 and sizeof(BYTE) == 1.
But I'm not sure what you mean by "converting int to hex". If you want a hex string representation, you'll be much better off just using one of standard methods of doing it.
For example, on last line I use std::hex to print numbers as hex.
Here is solution to what you've been asking for and a little more (live example: http://codepad.org/rsmzngUL):
#include <iostream>
using namespace std;
int main() {
const int value = 1200;
unsigned char set[] = { 0xA8,0x12,0x84,0x03,0x00,0x00 };
for (const unsigned char* c = set; c != set + sizeof(set); ++c) {
cout << static_cast<int>(*c) << endl;
}
cout << endl << "Putting value into array:" << endl;
*reinterpret_cast<int*>(&set[2]) = value;
for (const unsigned char* c = set; c != set + sizeof(set); ++c) {
cout << static_cast<int>(*c) << endl;
}
cout << endl << "Printing int's bytes one by one: " << endl;
for (int byteNumber = 0; byteNumber != sizeof(int); ++byteNumber) {
const unsigned char oneByte = reinterpret_cast<const unsigned char*>(&value)[byteNumber];
cout << static_cast<int>(oneByte) << endl;
}
cout << endl << "Printing value as hex: " << hex << value << std::endl;
}
UPD: From comments to your question:
1. If you need just getting separate digits out of the number in separate bytes, it's a different story.
2. Little vs Big endianness matters as well, I did not account for that in my answer.
did you mean this ?
#include <stdio.h>
#include <stdlib.h>
#define BYTE unsigned char
int main ( void )
{
BYTE set[6] = { 0xA8,0x12,0x84,0x03,0x00,0x00, } ;
sprintf ( &set[2] , "%d" , 1200 ) ;
printf ( "\n%c%c%c%c", set[2],set[3],set[4],set[5] ) ;
return 0 ;
}
output :
1200
however,thanks everyone who help me.
I want to get the VmRSS value from /proc/pid/status,below is the code
int main()
{
const int PROCESS_MEMORY_FILE_LEN = 500;
FILE *file;
std::string path("/proc/4378/status");
//path += boost::lexical_cast<std::string>( pid );
//path += "/status";
if(!(file = fopen(path.c_str(),"r")))
{
std::cout <<"open " << path<<"is failed " << std::endl;
return float(-1);
}
char fileBuffer[PROCESS_MEMORY_FILE_LEN];
memset(fileBuffer, 0, PROCESS_MEMORY_FILE_LEN);
if(fread(fileBuffer, 1, PROCESS_MEMORY_FILE_LEN - 1, file) != (PROCESS_MEMORY_FILE_LEN - 1))
{
std::cout <<"fread /proc/pid/status is failed"<< std::endl;
return float(-1);
}
fclose(file);
unsigned long long memoryUsage = 0;
int a = sscanf(fileBuffer,"VmRSS: %llu", &memoryUsage);
std::cout << a << std::endl;
std::cout << memoryUsage << std::endl;
}
at last,thanks
Based on your comments: To find VmRSS within your char array use C++ algorithms in combination with the C++ string library. Then you'll get the position of VmRSS and all you'll have to do is to retrieve the wanted result. With a little knowledge of the structure of these entries, this should be an easy task.
In addition to that it might be better to use fstream for reading directly into a string.