Writing a fixed length byte array to a binary file in Matlab - c++

I need to write a binary file from Matlab which is going to read by a c program.
the .h files defines the string I'm trying to write as
char elem[16]
On the matlab side:
str = 'abc' % A variable length string <= 15 chars
fwrite(fp, str, 'char*1')
I'm not sure how to force matlab to add a null char to str and buffer it with "garbage" until the proper size so the c program can read it.
Note I can't modify the c code so I need to get Matlab to write out the file in the proper format.

The following code is what I ended up with. Zeros ended up being the null character. Not sure if there is a more elegant solution.
out_str = "abc";
out_len = 16;
fwrite(fid_out, out_str, 'char*1');
fwrite(fid_out, zeros(1,out_len - length(out_str)),'char*1');

Related

SdFat write floats to file ESP32

I Need to write float or Strings value into the SDVolume Cache in SDFAT library, I'm using ESP32 with SdCard module.
uint8_t* pCache = (uint8_t*)sd.vol()->cacheClear();
memset(pCache, ' ', 512);
for (uint16_t i = 0; i < 512; i += 4) {
pCache[i + 0] = 'r'; // I Need to write a Float value or String into this cell
pCache[i + 1] = ',';
pCache[i + 2] = '0';
pCache[i + 3] = '\n';
}
Libray link: https://github.com/greiman/SdFat
First:
// I Need to write a Float value or String into this cell
makes no sense - that "cell" is a single character, like 'e'. How do you write a full float value into a single character?
You probably just want to fill pCache with a string representation of your float. So do that!
We've got all C++ at our disposal, so let's use a somewhat memory efficient method:
std::to_chars is the C++ way to convert numeric values to strings. Something like
#include <charconv>
…
std::to_chars(pCache, pCache+512-1, floatvalue);
would be appropriate.
Couple of things:
You need to zero-terminate strings if your needs to be able to know where they end. So, instead of memset(pCache, ' ', 512), memset(pCache, 0, 512); would be more sensible.
Are you sure your even using the right functions? vol()->cacheClear() is pretty unambigously marked as "do not use in your application" here! It also seems to be very unusual to me that you would write your string to some block device cache instead of getting a buffer for a file from the file system, or passing a buffer to the file system to write to a file.

To many char read by fread

Im am trying to open a file in binary mode and write the content to a buffer in C++.
I am using fread for this. However something goes wrong.
My code is:
FILE * in = fopen("in", "rb");
_in = new unsigned char [length_in];
fread(_in, sizeof(char), length_in, in);
When debugging i can see that _in = unsigned char * "Asdfghjkl\x1f \x10" .
When rebuilding the program, the part \x1f \x10 changes randomly or disappears.
What i am expecting is always _in = unsigned char * "Asdfghjkl" .
When replacing length_in with 9 i still get something like"Asdfghjkl\x1f \x10" .
What am I missing. I am using a Mac and Xcode.
Your array is created uninitialized, so those are garbage values from whatever was in memory beforehand. Initialize it to zeros like this:
_in = new unsigned char [length_in]();
Also fread returns the number of bytes read. If you’re treating it like a string, make sure the result is null-terminated.

Weird characters when trying to grab char * from fstream

I am trying to read 4 characters at a specific position from a file. The code is simple but the result is really confusing:
fstream dicomFile;
dicomFile.open(argv[1]);
dicomFile.seekg(128,ios::beg);
char * memblock = new char [4];
dicomFile.read(memblock,4);
cout<<"header is "<<memblock<<endl;
Ideally the result should be "DICM" but the actual result from the console was "DICM" plus weird characters, as shown in the picture. What's more, every time I run it, the characters are different. I suppose this may be something about ASCII and Unicode, I tried to change project property from Unicode to multibytes and then change back, no difference.
Does anyone know what's happening here and how do I solve it please? Thanks very much!
C style (char *) strings use the concept of null-terminators. This means strings are ended with a '\0' character in their last element. You are reading in exactly 4 characters into a 4 character buffer, which does not include a null character to end the string. C and C++ will happily run right off the end of your buffer in search for the null terminator that signifies the end of the string.
Quick fix is to create a block of length + 1, read in length data, then set str[length] = '\0'. In your case it would be as below.
char * memBlock = new char [5];
// populate memBlock with 4 characters
memBlock[ 4 ] = '\0';
A better solution is to use std::string instead of char * when working with strings in C++.
You could also initialize the buffer with zeros, putting null-terminators at every location.
char * memblock = new char [5](); // zeros, and one element longer
Fairly inefficient though.

strstr not able to search the string inside the data in octal format

I am trying to find a string in the given file (actually the file is tar file(please pay attention here) and i opened the file in notepad++ and took randomly a string from that opened file) and i stored that full tar file in a buffer and now i want to find the position of the string i copied using strstr function in the stored buffer.
The code to do is this(which is absolutely correct)-
char *compare= "_.png"; //suppose this is the copied string
//which is to be find out in buffer using strstr
char * StartPosition;
StartPosition = strstr (buffer,compare);
__int64 count=0;
MessageBox(m_hwndPreview,L"before the while loop",L"BTN WND6",MB_ICONINFORMATION);
while (StartPosition!=NULL)
{
MessageBox(m_hwndPreview,L"hurr inside the while loop",L"BTN WND6",MB_ICONINFORMATION);
MessageBoxA(m_hwndPreview,strerror(errno),"BTN WND4", MB_ICONINFORMATION);
count=StartPosition-buffer+1;
return 0;
}
and suppose if i have content of tar file in notepad like as below from where i copied this string stored in compare-
3_VehicleWithKinematicsAndAerodynamics_.000.png IHDR (here is some strange data which can't be copied and also there are lot of NULL but we have to find out the position of "_.png" so not so difficult in this case ).
The question is my code works fine until i store the data before the .png then i am able to find its position using strstr the problem is when i try to find out the string postion which is appearing after
`3_VehicleWithKinematicsAndAerodynamics_.000.png IHDR ...suppose here we have strange data (which is data block if we see the tar parser)...after this we have another file like..."3_VehicleWithKinematicsAndAerodynamics_.html"`
and if i want to find this "3_VehicleWithKinematicsAndAerodynamics_.html" using strstr then i am not able to find it due to strange data in between them.(because i think that those data are not recognized by the compiler and dut to that i am not able to access the file which is located after the strange data)
to make more clear see the location of file in tar file is as follows-
3_VehicleWithKinematicsAndAerodynamics_.000.png IHDR ............(its data blocl-which is strange contents if you open in tar file)....3_VehicleWithKinematicsAndAerodynamics_.000.html
i have to access the .html file using strstr . why it is not accessing it ?? any ideas ?? *
PLEASE GIVE THE ALTERNATIVES TO ACHIEVE IT..I am sure what i try won't work..
A C style string is a number of characters terminated by a zero-character (NUL character - the value zero, not the character '0'). This means that strstr will stop as soon as it hits such a byte.
One solution that is quite plausible is to simply write a function that searches through binary data based on it's length, not on a "terminating character".
Something like this (this still assumes that the str is a C style string):
char *find_str_in_data(const char *str, const char *data, int length)
{
int pos = 0;
int slen = strlen(str);
while(pos < length-slen)
{
int i = 0;
while(i < slen && str[i] = data[pos+i])
{
i++;
}
if (i == slen)
return data + pos;
}
return NULL;
}
If you really want to use strstr then you need to escape the string contained in buffer with '\0'. If you know the size of data that was put into the buffer (let's say, sizeOfData), than you could do something like this before you use strstr:
buffer[sizeOfData] = '\0';
Warning: if sizeOfData is equal to the size of buffer, then you will either need a greater buffer or overwrite the last character with '\0' (in the second case you should check the buffer tail manually, because the character you've overwritten could be one of the characters of sequence you are looking for).

C++, Storing a String containing binary into a text file

I am currently attempting to store a string containing binary code.
When I attempt to write this string to a text file it simply stores each 0 and 1 character in a string format, rather than storing it into 8 bit chunks as I require. This causes the file to be larger than intended, considering it uses 8 bits to store each 0 and 1.
Should I write the string to a .bin file instead of a .txt file?
If so how would I go about doing this, and if possible an example with some working code.
My thanks for any advice in advance.
string encoded = "01010101";
ofstream myfile;
myfile.open ("encoded");
myfile << encoded;
myfile.close();
Clarification:
I have a string made up of 1's and 0's(resulting from a Huffman Tree), I wish to break this string up into 8 bit chunks, I wish to write each character represented by said chink to a compressed file.
std::bitset can convert a string to an integer.
std::bitset<8> bits("01010101");
cout << bits.to_ullong();
I'm only guessing since you don't show any code, but it seems you have a string containing the characters '1' and '0'. If you write that to a file of course it will be as a text. You need to convert it to integers first.
See e.g. std::stoi or std::strtol for functions to convert strings of arbitrary base to integers.
Should I write the string to a .bin file instead of a .txt file?
If you wish so... But that wouldn't make a difference either. ofstream doesn't care about filenames. Just convert the string to a byte (uint8_t) and write that byte to the file:
string s = "10101010";
uint8_t byte = strtoul(s.c_str(), NULL, 2);
myfile << byte;