C++ convert HexString to extended Ascii code not show correct ascii code in the text file - c++

How to convert hex string to extended ascii code symbol code and write the converted codes to the text file.
Example input string:
std:string strInput = "FF2139FF"
Example output string should be "ÿ!9ÿ" in the text file.
I tried to write the program as below to write to a text file.
#include <string>
using namespace std;
string ConvertHexStringToAsciiString(string sInputHexString, int step)
{
int len = sInputHexString.length();
string sOutputAsciiString;
for (int i = 0; i < len; i += step)
{
string byte = sInputHexString.substr(i, step);
char chr = (char)(int)strtol(byte.c_str(), nullptr, 16);
sOutputAsciiString.push_back(chr);
}
return sOutputAsciiString;
}
void main()
{
string sInputHexString = "FF2139FF";
string sOutputAsciiString = "";
sOutputAsciiString = ConvertHexStringToAsciiString(sInputHexString, 2);
const char* sFileName = "E:\\MyProgramDev\\Convert_HexString_To_AsciiCode\\Convert_HexString_To_AsciiCode\\TestFolder\\1.txt";
FILE* file = fopen(sFileName, "wt");
if (nullptr != file)
{
fputs(sOutputAsciiString.c_str(), file);
fclose(file);
}
}
It seems working but when I open the text file 1.txt with notepad, I cannot see the ÿ and only !9 displayed. I am not sure how to display it correctly using notepad or my code is wrong?
Thanks.

Use better notepad - or even better, any hexeditor to view result.
Try for example XVI 32 hex editor

I found a way to do thing, Split this HexString FF to two BYTE(unsigned char) "F" and "F", and then construct together and convert to decimal. It can show the correct letter.

Related

Encoding Vietnamese characters from ISO88591, UTF8, UTF16BE, UTF16LE, UTF16 to Hex and vice versa using C++

I have edited my post. Currently what I'm trying to do is to encode an input string from the user and then convert it to Hex formats. I can do it properly if it does not contain any Vietnamese character.
If my inputString is "Hello". But when I try to input a string such as "Tôi", I don't know how to do it.
enum Encodings { USASCII, ISO88591, UTF8, UTF16BE, UTF16LE, UTF16, BIN, OCT, HEX };
switch (Encodings)
{
case USASCII:
ASCIIToHex(inputString, &ascii); //hello output 48656C6C6F
return new ByteField(ascii.c_str());
case ISO88591:
ASCIIToHex(inputString, &ascii);//hello output 48656C6C6F
//tôi output 54F469
return new ByteField(ascii.c_str());
case UTF8:
ASCIIToHex(inputString, &ascii);//hello output 48656C6C6F
//tôi output 54C3B469
return new ByteField(ascii.c_str());
case UTF16BE:
ToUTF16(inputString, &ascii, Encodings);//hello output 00480065006C006C006F
//tôi output 005400F40069
return new ByteField(ascii.c_str());
case UTF16:
ToUTF16(inputString, &ascii, Encodings);//hello output FEFF00480065006C006C006F
//tôi output FEFF005400F40069
return new ByteField(ascii.c_str());
case UTF16LE:
ToUTF16(inputString, &ascii, Encodings);//hello output 480065006C006C006F00
//tôi output 5400F4006900
return new ByteField(ascii.c_str());
}
void StringUtilLib::ASCIIToHex(std::string s, std::string * result)
{
int n = s.length();
for (int i = 0; i < n; i++)
{
unsigned char c = s[i];
long val = long(c);
std::string bin = "";
while (val > 0)
{
(val % 2) ? bin.push_back('1') :
bin.push_back('0');
val /= 2;
}
reverse(bin.begin(), bin.end());
result->append(ConvertBinToHex(bin));
}
}
std::string ToUTF16(std::string s, std::string * result, int encodings) {
int n = s.length();
if (encodings == UTF16) {
result->append("FEFF");
}
for (int i = 0; i < n; i++)
{
int val = int(s[i]);
std::string bin = "";
while (val > 0)
{
(val % 2) ? bin.push_back('1') :
bin.push_back('0');
val /= 2;
}
reverse(bin.begin(), bin.end());
if (encodings == UTF16 || encodings == UTF16BE) {
result->append("00" + ConvertBinToHex(bin));
}
if (encodings == UTF16LE) {
result->append(ConvertBinToHex(bin) + "00");
}
}
}
std::string ConvertBinToHex(std::string str) {
long long temp = atoll(str.c_str());
int dec_value = 0;
int base = 1;
int i = 0;
while (temp) {
int last_digit = temp % 10;
temp = temp / 10;
dec_value += last_digit * base;
base = base * 2;
}
char hexaDeciNum[10];
while (dec_value != 0)
{
int temp = 0;
temp = dec_value % 16;
if (temp < 10)
{
hexaDeciNum[i] = temp + 48;
i++;
}
else
{
hexaDeciNum[i] = temp + 55;
i++;
}
dec_value = dec_value / 16;
}
str.clear();
for (int j = i - 1; j >= 0; j--) {
str = str + hexaDeciNum[j];
}
return str;
}
The question is completely unclear. To encode something you need an input right? So when you say "Encoding Vietnamese Character to UTF8, UTF16" what's your input string and what's the encoding before converting to UTF-8/16? How do you input it? From file or console?
And why on earth are you converting to binary and then to hex? You can print directly to binary and hex from the bytes, no need to convert from binary to hex. Note that converting to binary like that is fine for testing but vastly inefficient in production code. I also don't know what you mean by "But what if my letter is "Á" or "À" which is a Vietnamese letter I cannot get the value of it". Please show a minimal, reproducible example along with the input/output
But I think you just want to output the UTF encoded bytes from a string literal in the source code like "ÁÀ". In that case it isn't called "encoding a string" but just "outputting a string"
Both Á and À in Unicode can be represented by precomposed characters (U+00C1 and U+00C0) or combining characters (A + U+0301 ◌́/U+0300 ◌̀). You can switch between them by selecting "Unicode dựng sẵn" or "Unicode tổ hợp" in Unikey. Suppose you have those characters in string literal form then std::string str = "ÁÀ" contains a series of bytes that corresponds to the above letters in the source file encoding. So depending on which encoding you save the *.cpp file as (CP1252, CP1258, UTF-8...), the output byte values will be different
To force UTF-8/16/32 encoding you just need to use the u8, u and U suffix respectively, along with the correct type (char8_t, char16_t, char32_t or std::u8string/std::u16string/std::u32string)
std::u8string utf8 = u8"ÁÀ";
std::u16string utf16 = u"ÁÀ";
std::u32string utf32 = U"ÁÀ";
Then just use c_str() to get the underlying buffers and print the bytes. In C++14 std::u8string is not available yet so just save the file as UTF-8 and use std::string. Similarly you can read std::u*string directly from std::cin to print the encoding of a user-input string
Edit:
To convert between UTF encodings use the standard std::codecvt, std::wstring_convert, std::codecvt_utf8_utf16...
Working on non-Unicode encodings is trickier and needs some external library like ICU or OS-dependent APIs
WideCharToMultiByte and MultiByteToWideChar on Windows
iconv on Linux
Limiting to ISO-8859-1 makes it easier but you still need many lookup tables, and there's no way to convert other encodings to ASCII without loss of information
-64 is the correct representation of À if you are using signed char and CP1258. If you want a positive number you need to cast to unsigned char first.
If you are indeed using CP1258, you are probably on Windows. To convert your input string to UTF-16, you probably want to use a Windows platform API such as MultiByteToWideChar which accepts a code page parameter (of course you have to use the correct code page). Alternatively you may try a standard function like mbstowcs but you need to set up your locale correctly before using it.
You might find it easier to switch to wide characters throughout your application, and avoid most transcoding.
As a side note, converting an integer to binary only to convert that to hexadecimal is not an easy or efficient way to display a hexadecimal representation of an integer.

C++ reading in strings and characters

Hi everyone I am working on a project for my CS class and I can't figure out how to read in part of my data file.
63f7hj-9 22spaces L Is this correct
My data file consists of this line of data and I have to figure out how to read in portions of it. I have to read in the 63 and save it as an integer and I do not need the f7hj-9. I also need to read in the 22spaces and save it as a string and the L as a character.
The phrase "Is this correct" needs to go into the console.
So my question is, how do I read in just the 63 and discard the rest of it?
Save the phrase "22 spaces" as a string.
L as a character
And the phrase "Is this correct" as a string.
I am new to c++ and I have gotten parts of this project to work but I'm stuck on this part.
Thank you for the help.
Reading input from file and splitting the line 63f7hj-9 L Is this correct into integer as 63, ignoring 7hj-9 and then reading the 22 spaces in space1 string and then reading character L as a character and the rest of the string " Is this correct" inside the string str2.
This is an example of how you can use fscanf(or scanf) to achieve this.
%d will read the integer as it is the format specifier for integer
Next we need to ignore the "f7hj-9" from the file so just writing it as it is will do the job
Next we need to read 22 spaces so %22c will read 22 characters irrespective of whether the character is a newline or space(here 22 spaces)
Next we need to read a character so %c will store it in char c
Now another %*c will ignore the one whitespace after L
using %[^\n]s will read the rest of the string until newline
#include <stdio.h>
int main() {
int n;
char c;
char space1[23];
char str2[32];
FILE *fp;
fp = fopen("b.txt", "r");
if(fp == NULL) {
printf("Failed to open the file\n");
return 1;
}
if(fscanf(fp, "%df7hj-9%22c%c%*c%[^\n]s", &n, space1, &c, str2) != 4) {
printf("Read failure\n");
return 1;
}
printf("Integer = %d\n", n);
printf("Spaces = %sEnd\n", space1);
printf("Character = %c\n", c);
printf("String = %s", str2);
return 0;
}
Input:
63f7hj-9 L Is this correct
Output:
Integer = 63
Spaces = End
Character = L
String = Is this correct

Reading null characters into char array for hex conversion

I am writing a program which reads input from a text file and converts it to hexadecimal for later processing.
ifstream fin("input.txt"); //open file with ifstream
if(fin.is_open()){ //check if file is open
for(int i = 0; i<length; i++){ //int length for how many characters I need
fin.get(buffer[i]); //write into char array buffer[256]
}
}
else{
cout<<"Can't open file";
exit(0);
}
fin.close();
So everything is fine, it opens up nicely and gets exactly as many characters as I need from there, later I use a function to turn that into a hexadecimal string:
std::string string_to_hex(const std::string input)
{
static const char* const lut = "0123456789ABCDEF";
size_t len = input.length();
string output;
output.reserve(2 * len);
for (size_t i = 0; i < len; ++i)
{
const unsigned char c = input[i];
output.push_back(lut[c >> 4]);
output.push_back(lut[c & 15]);
}
return output;
}
which also works fine, it gives me the correct hexadecimal value for the characters that I get.
Now here is the problem: my file contains null characters (hexadecimal "00" characters aka '\0') which I need to read into my program and do a proper conversion so every null character in my array after conversion should look like "00". Every time I
try to convert null characters in my array they change into spaces (hexadecimal "20"), which ruins my data for processing later. Changing "20" into "00" is also not an option since the file contains real spaces that also need to be properly processed.
This is my first time working with null characters and I am absolutely confused on how to properly process them. All I know is that null characters are used at the end of a string or an array so when I print them out the program would know when to stop.
I do not know how I should do it properly. I tried opening the file differently using fopen, I tried copying my input.txt into an array differently. Maybe it copies it properly but the hex conversion doesn't work. Maybe I shouldn't send it as a string for conversion. I don't know. I also noticed that when I tried to copy paste a sample from the file to another file, all the null characters have been replaced by spaces, maybe it has something to do with this?

Write encrypted wstring to wofstream

I have a simple "encryption" function that works with wstring variables and I want to write the result of this function into a file, using wofstream.
This is my code:
void save_file() {
wstring text = L"Text to be encrypted. The text is encrypted but not saved";
wstring enctext = encrypt(text);
wprintf_s(L"%s\n", enctext);
wofstream output_stream;
output_stream.open(L"myfile.enc");
output_stream<< enctext ;
output_stream.close();
}
wstring encrypt(wstring decrypted) {
wstring encrypted;
for (unsigned int i=0; i<decrypted.length(); i++) {
encrypted += wchar_t(int(decrypted[i]) + 128);
}
return encrypted;
}
So, the problem with this piece of ... code is that although the wprintf_s function outputs the entire encrypted text, in the written file I only see the characters inside the ASCII range (or at least is what it seems to me). The encrypted text is saved until an unknown character is found (displayed by ? in the console). I want to save any character, and I want them saved as wide chars (1 word each one). How can I do this?
You need to use fwrite() or the iostream equivalent to write binary data. fprintf() and eqivalents are for text (as in readable text, not binary).

Need Convert Binary file to Txt file

I have a dat(binary) file but i wish to convert this file into Ascii (txt) file using c++ but i am very new in c++ programming.so I juct opend my 2 files:myBinaryfile and myTxtFile but I don't know how to read data from that dat file and then how to write those data into new txt file.so i want to write a c+ codes that takes in an input containing binary dat file, and converts it to Ascii txt in an output file. if this possible please help to write this codes. thanks
Sorry for asking same question again but still I didn’t solve my problem, I will explain it more clearly as follows: I have a txt file called “A.txt”, so I want to convert this into binary file (B.dat) and vice verse process. Two questions:
1. how to convert “A.txt” into “B.dat” in c++
2. how to convert “B.dat” into “C.txt” in c++ (need convert result of the 1st output again into new ascii file)
my text file is like (no header):
1st line: 1234.123 543.213 67543.210 1234.67 12.000
2nd line: 4234.423 843.200 60543.232 5634.60 72.012
it have more than 1000 lines in similar style (5 columns per one line).
Since I don’t have experiences in c++, I am struggle here, so need your helps. Many Thanks
All files are just a stream of bytes. You can open files in binary mode, or text mode. The later simply means that it may have extra newline handling.
If you want your text file to contain only safe human readable characters you could do something like base64 encode your binary data before saving it in the text file.
Very easy:
Create target or destination file
(a.k.a. open).
Open source file in binary mode,
which prevents OS from translating
the content.
Read an octet (byte) from source
file; unsigned char is a good
variable type for this.
Write the octet to the destination
using your favorite conversion, hex,
decimal, etc.
Repeat at 3 until the read fails.
Close all files.
Research these keywords: ifstream, ofstream, hex modifier, dec modifier, istream::read, ostream::write.
There are utilities and applications that already perform this operation. On the *nix and Cygwin side try od, *octal dump` and pipe the contents to a file.
There is the debug utility on MS-DOS system.
A popular format is:
AAAAAA bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb bb cccccccccccccccc
where:
AAAAAA -- Offset from beginning of file in hexadecimal or decimal.
bb -- Hex value of byte using ASCII text.
c -- Character representation of byte, '.' if the value is not printable.
Please edit your post to provide more details, including an example layout for the target file.
Edit:
A complex example (not tested):
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>
using namespace std;
const unsigned int READ_BUFFER_SIZE = 1024 * 1024;
const unsigned int WRITE_BUFFER_SIZE = 2 * READ_BUFFER_SIZE;
unsigned char read_buffer[READ_BUFFER_SIZE];
unsigned char write_buffer[WRITE_BUFFER_SIZE];
int main(void)
{
int program_status = EXIT_FAILURE;
static const char hex_chars[] = "0123456789ABCDEF";
do
{
ifstream srce_file("binary.dat", ios::binary);
if (!srce_file)
{
cerr << "Error opening input file." << endl;
break;
}
ofstream dest_file("binary.txt");
if (!dest_file)
{
cerr << "Error creating output file." << endl;
}
// While no read errors from reading a block of source data:
while (srce_file.read(&read_buffer[0], READ_BUFFER_SIZE))
{
// Get the number of bytes actually read.
const unsigned int bytes_read = srce_file.gcount();
// Define the index and byte variables outside
// of the loop to maybe save some execution time.
unsigned int i = 0;
unsigned char byte = 0;
// For each byte that was read:
for (i = 0; i < bytes_read; ++i)
{
// Get source, binary value.
byte = read_buffer[i];
// Convert the Most Significant nibble to an
// ASCII character using a lookup table.
// Write the character into the output buffer.
write_buffer[i * 2 + 0] = hex_chars[(byte >> 8)];
// Convert the Least Significant nibble to an
// ASCII character and put into output buffer.
write_buffer[i * 2 + 1] = hex_chars[byte & 0x0f];
}
// Write the output buffer to the output, text, file.
dest_file.write(&write_buffer[0], 2 * bytes_read);
// Flush the contents of the stream buffer as a precaution.
dest_file.flush();
}
dest_file.flush();
dest_file.close();
srce_file.close();
program_status = EXIT_SUCCESS;
} while (false);
return program_status;
}
The above program reads 1MB chunks from the binary file, converts to ASCII hex into an output buffer, then writes the chunk to the text file.
I think you are misunderstanding that the difference between a binary file and a test file is in the interpretation of the contents.