commit 8b93cf4fc39c3f4be2f7129ca3615595a15983d0 Author: serr Date: Thu Jan 16 20:27:29 2025 +0300 v1.0 diff --git a/cod3k.h b/cod3k.h new file mode 100644 index 0000000..69978da --- /dev/null +++ b/cod3k.h @@ -0,0 +1,127 @@ +// Small module for correct Russian localization of programs written in C/C++ under Windows +#pragma once +#include +#include +#include +#include +#include + +#define WT _T // WT = widechar text - Macro for declaring constant widechar strings +#define W_SET wmemset // Memset for wchar + +// Internal functions of the module, not intended for use in user code +int set_unicode_mode(void); // Enable unicode mode +int set_default_mode(void); // Enable default mode +// + +void wwrite(TCHAR* dst, size_t dst_size); // Input wide char characters from console into array +void wprint(wchar_t* format, ...); // Formatted output of wide char array to console +void bwprint(wchar_t* arr, size_t size); // Output wide char array in binary form to console +void bcprint(char* arr, size_t size); // Output char array in binary form to console +TCHAR* ctow(char* arr1, TCHAR* arr2); // Converts char array to wide char array +char* wtoc(TCHAR* arr1, char* arr2); // Converts wide char array to char array + +enum COD3K_ERRORS { + SETMODE_ERROR_STDIN = -228, + SETMODE_ERROR_STDOUT, + SETMODE_ERROR_STDERR +}; + +// Enable Unicode mode +int set_unicode_mode(void) { + int err_inp, err_out, err_err; + if ((err_inp = _setmode(_fileno(stdin), _O_WTEXT)) == -1) { // Unicode mode for input stream + return SETMODE_ERROR_STDIN; + } + if ((err_inp = _setmode(_fileno(stdout), _O_WTEXT)) == -1) { // Unicode mode for output stream + return SETMODE_ERROR_STDOUT; + } + if ((err_err = _setmode(_fileno(stderr), _O_WTEXT)) == -1) { // Unicode mode for error stream + return SETMODE_ERROR_STDERR; + } +} + +// Disable Unicode mode +int set_default_mode(void) { + int err_inp, err_out, err_err; + if ((err_inp = _setmode(_fileno(stdin), _O_TEXT)) == -1) { // Restore mode for input stream + return SETMODE_ERROR_STDIN; + } + if ((err_out = _setmode(_fileno(stdout), _O_TEXT)) == -1) { // Restore mode for output stream + return SETMODE_ERROR_STDOUT; + } + if ((err_err = _setmode(_fileno(stderr), _O_TEXT)) == -1) { // Restore mode for error stream + return SETMODE_ERROR_STDERR; + } + return 0; +} + +// Formatted output of wide char array to console +void wprint(const wchar_t* format, ...) { + set_unicode_mode(); + va_list args; + va_start(args, format); vfwprintf(stdout, format, args); va_end(args); + set_default_mode(); +} + +// Function to print the first 'size' characters of wchar_t array in binary form +void bwprint(wchar_t* arr, size_t size) { + for (size_t i = 0; i < size; i++) { + for (int j = sizeof(wchar_t) * 8 - 1; j >= 0; j--) { + putchar((arr[i] & (1 << j)) ? '1' : '0'); + } + putchar(' '); + } + putchar('\n'); +} + +// Function to print the first 'size' characters of char array in binary form +void bcprint(char* arr, size_t size) { + for (size_t i = 0; i < size; i++) { + for (int j = sizeof(char) * 8 - 1; j >= 0; j--) { + putchar((arr[i] & (1 << j)) ? '1' : '0'); + } + putchar(' '); + } + putchar('\n'); +} + +// dst - TCHAR a.k.a wchar_t array, into which characters from console will be written, size - size of this array +// removes newline character +void wwrite(TCHAR* dst, size_t dst_size) { + set_unicode_mode(); + fgetws(dst, dst_size, stdin); dst[wcslen(dst) - 1] = 0; + set_default_mode(); +} + +// char to wide char conversion +TCHAR* ctow(char* arr1, TCHAR* arr2) { + int i = 0; + for (char* p_byte = arr1; *p_byte != 0; ++p_byte) { + char byte = *p_byte; + if (byte & 0x80) { // bit at position 8 is set => Russian text + // clear bit at position 8 + + // set bit at position 11 (this is necessary for correct wide char if the text is not ASCII) + arr2[i] = byte & 0x7F | 0x400; + } + else { // English text + arr2[i] = byte; + } + ++i; + } + return arr2; +} + +// widechar to char +char* wtoc(TCHAR* arr1, char* arr2) { + int i = 0; + for (TCHAR* p_wbyte = arr1; *p_wbyte != 0; ++p_wbyte) { + TCHAR wbyte = *p_wbyte; + arr2[i] = (char)(wbyte & 0xFF); // lower 8 bits + if (wbyte & 0x400) { // if the 11th bit is set, the text is Russian + arr2[i] |= 0x80; // marker for Russian text in char - set the 8th bit + } + ++i; + } + return arr2; +} \ No newline at end of file diff --git a/example.cpp b/example.cpp new file mode 100644 index 0000000..74da166 --- /dev/null +++ b/example.cpp @@ -0,0 +1,26 @@ +#include +#include "cod3k.h" // включение библиотеки + +#define SZ 256 + +int main(void) +{ + // Пример 1 - пример работы в wide char + wprint(WT("Введите текст: ")); + TCHAR bufferW[SZ] = { 0 }; wwrite(bufferW, SZ); // считываю символы из консоли + wprint(WT("Содержимое bufferW: %s\n"), bufferW); bwprint(bufferW, 20); + + char buffer[SZ] = { 0 }; + wtoc(bufferW, buffer); // конвертация widechar в char + wprint(WT("bufferc в бинарном виде: ")); bcprint(buffer, 20); + + W_SET(bufferW, SZ, 0); + ctow(buffer, bufferW); // конвертация обратно + wprint(WT("Содержимое bufferW: %s\n"), bufferW); bwprint(bufferW, 20); + + + return 0; +} + + +