Skip to content

Instantly share code, notes, and snippets.

@7h3w4lk3r
Last active January 23, 2025 14:51
Show Gist options
  • Select an option

  • Save 7h3w4lk3r/3f0ac29713b11ad01c8cd2894550d2c9 to your computer and use it in GitHub Desktop.

Select an option

Save 7h3w4lk3r/3f0ac29713b11ad01c8cd2894550d2c9 to your computer and use it in GitHub Desktop.
Custom printf helper function using Win32 API instead of CRT function (printf)
#include <windows.h> // Include Windows API
// Debug print toggle, comment this to disable debug print statements
#define DEBUG_PRINT
// Function to write a string to the console
void write_to_console(const char* str, int length) {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD written;
WriteConsoleA(hConsole, str, length, &written, NULL);
}
// Custom function to convert integer to string
void my_itoa(int value, char* str, int base) {
int i = 0;
int isNegative = 0;
// Handle 0 explicitly
if (value == 0) {
str[i++] = '0';
str[i] = '\0';
return;
}
// Handle negative integers
if (value < 0 && base == 10) {
isNegative = 1;
value = -value;
}
// Process individual digits
while (value != 0) {
int remainder = value % base;
str[i++] = (remainder > 9) ? (remainder - 10) + 'a' : remainder + '0';
value = value / base;
}
// Append negative sign for negative numbers
if (isNegative) {
str[i++] = '-';
}
// Null-terminate the string
str[i] = '\0';
// Reverse the string
for (int j = 0; j < i / 2; j++) {
char temp = str[j];
str[j] = str[i - j - 1];
str[i - j - 1] = temp;
}
}
// Custom function to convert pointer to hexadecimal string
void my_ptrtoa(void* ptr, char* str, int max_size) {
unsigned long long value = (unsigned long long)ptr;
int i = 0;
if (max_size < 3) {
return;
}
if (value == 0) {
str[i++] = '0';
}
else {
while (value != 0 && i < max_size - 1) {
int remainder = value % 16;
str[i++] = (remainder > 9) ? (remainder - 10) + 'a' : remainder + '0';
value = value / 16;
}
}
for (int j = 0; j < i / 2; j++) {
char temp = str[j];
str[j] = str[i - j - 1];
str[i - j - 1] = temp;
}
str[i] = '\0';
}
// Print function that accepts a format string and various arguments
void printd(const char* format, ...) {
#ifdef DEBUG_PRINT
char buffer[256];
char temp[64]; // Temporary buffer for formatted output
int i = 0, j = 0;
va_list args;
va_start(args, format); // Initialize va_list
while (format[i] != '\0') {
if (format[i] == '%') {
i++;
if (format[i] == 's') { // Handle string
const char* str = va_arg(args, const char*);
while (*str != '\0' && j < sizeof(buffer) - 1) {
buffer[j++] = *str++;
}
}
else if (format[i] == 'd') { // Handle integer
int num = va_arg(args, int);
my_itoa(num, temp, 10);
for (int k = 0; temp[k] != '\0'; k++) {
buffer[j++] = temp[k];
}
}
else if (format[i] == 'c') { // Handle character
char ch = (char)va_arg(args, int);
buffer[j++] = ch;
}
else if (format[i] == 'p') { // Handle pointer
void* ptr = va_arg(args, void*);
my_ptrtoa(ptr, temp, sizeof(temp));
for (int k = 0; temp[k] != '\0'; k++) {
buffer[j++] = temp[k];
}
}
else {
// Handle unknown specifier
buffer[j++] = '%';
buffer[j++] = format[i];
}
}
else {
buffer[j++] = format[i];
}
i++;
}
buffer[j] = '\0';
write_to_console(buffer, j);
va_end(args); // Clean up va_list
#endif
}
// Main function to demonstrate the print functionality
int main() {
char a[] = "test";
int num = 42;
char ch = 'A';
printd("String is: %s\nInteger is: %d\nCharacter is: %c\nPointer is: %p\n", a, num, ch, &num);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment