Introduction to String Formatting
String formatting in C is the process of creating formatted strings using various functions from the standard library. It's essential for output, logging, data serialization, and creating human-readable representations of data.
String Formatting Architecture Overview
String Formatting System ├── Format Specifiers │ ├── %d - Integers │ ├── %f - Floating point │ ├── %s - Strings │ ├── %c - Characters │ └── %p - Pointers ├── Formatting Functions │ ├── printf() - Print to stdout │ ├── fprintf() - Print to file │ ├── sprintf() - Print to string │ ├── snprintf() - Safe string print │ └── asprintf() - Allocate and print └── Format Modifiers ├── Width and precision ├── Left/right alignment ├── Zero padding └── Sign handling
Basic printf() Formatting
1. Basic Format Specifiers
#include <stdio.h> int main() { int integer = 42; float floating = 3.14159; double double_val = 2.71828; char character = 'A'; char string[] = "Hello, World!"; void* pointer = &integer; printf("=== Basic Format Specifiers ===\n\n"); printf("Integer (%%d): %d\n", integer); printf("Integer (%%i): %i\n", integer); printf("Unsigned (%%u): %u\n", integer); printf("Hexadecimal (%%x): %x\n", integer); printf("Hexadecimal (%%X): %X\n", integer); printf("Octal (%%o): %o\n", integer); printf("\nFloating point (%%f): %f\n", floating); printf("Floating point (%%F): %F\n", floating); printf("Scientific (%%e): %e\n", floating); printf("Scientific (%%E): %E\n", floating); printf("Shortest (%%g): %g\n", floating); printf("Shortest (%%G): %G\n", floating); printf("\nDouble (%%lf): %lf\n", double_val); printf("\nCharacter (%%c): %c\n", character); printf("String (%%s): %s\n", string); printf("\nPointer (%%p): %p\n", pointer); printf("Percent sign: %%\n"); return 0; } Output:
=== Basic Format Specifiers === Integer (%d): 42 Integer (%i): 42 Unsigned (%u): 42 Hexadecimal (%x): 2a Hexadecimal (%X): 2A Octal (%o): 52 Floating point (%f): 3.141590 Floating point (%F): 3.141590 Scientific (%e): 3.141590e+00 Scientific (%E): 3.141590E+00 Shortest (%g): 3.14159 Shortest (%G): 3.14159 Double (%lf): 2.718280 Character (%c): A String (%s): Hello, World! Pointer (%p): 0x7ffc12345678 Percent sign: %
2. Format Modifiers
#include <stdio.h> int main() { int num = 42; float pi = 3.14159; char text[] = "Hello"; printf("=== Format Modifiers ===\n\n"); // Width specification printf("Width modifiers:\n"); printf("[%5d]\n", num); // Right align, width 5 printf("[%-5d]\n", num); // Left align, width 5 printf("[%05d]\n", num); // Zero pad, width 5 printf("[%+5d]\n", num); // Show sign, width 5 printf("[% d]\n", num); // Space for positive numbers printf("\nPrecision modifiers:\n"); printf("[%.2f]\n", pi); // 2 decimal places printf("[%.5f]\n", pi); // 5 decimal places printf("[%8.2f]\n", pi); // Width 8, 2 decimals printf("[%08.2f]\n", pi); // Zero pad, width 8, 2 decimals printf("\nString modifiers:\n"); printf("[%10s]\n", text); // Right align, width 10 printf("[%-10s]\n", text); // Left align, width 10 printf("[%.3s]\n", text); // First 3 characters printf("[%10.3s]\n", text); // Width 10, first 3 chars printf("\nCombined modifiers:\n"); printf("|%8d|%-8d|%08d|\n", 123, 123, 123); printf("|%8.2f|%-8.2f|%08.2f|\n", pi, pi, pi); return 0; } Output:
=== Format Modifiers === Width modifiers: [ 42] [42 ] [00042] [ +42] [ 42] Precision modifiers: [3.14] [3.14159] [ 3.14] [00003.14] String modifiers: [ Hello] [Hello ] [Hel] [ Hel] Combined modifiers: | 123|123 |00000123| | 3.14|3.14 |00003.14|
String Formatting Functions
1. sprintf() - Format to String
#include <stdio.h> int main() { char buffer[100]; char name[] = "Alice"; int age = 25; float height = 1.75; // Format into buffer int chars_written = sprintf(buffer, "Name: %s, Age: %d, Height: %.2f m", name, age, height); printf("Formatted string: %s\n", buffer); printf("Characters written: %d\n", chars_written); // Multiple sprintf calls char result[200] = ""; char temp[50]; sprintf(temp, "Name: %s\n", name); strcat(result, temp); sprintf(temp, "Age: %d\n", age); strcat(result, temp); sprintf(temp, "Height: %.2f\n", height); strcat(result, temp); printf("\nMulti-line result:\n%s", result); return 0; } 2. snprintf() - Safe String Formatting
#include <stdio.h> int main() { char buffer[20]; char long_text[] = "This is a very long string that won't fit"; printf("=== snprintf() - Buffer Overflow Protection ===\n\n"); // snprintf will truncate to fit buffer size int needed = snprintf(buffer, sizeof(buffer), "Data: %s", long_text); printf("Buffer size: %zu\n", sizeof(buffer)); printf("Buffer content: '%s'\n", buffer); printf("Characters needed (would have written): %d\n", needed); if (needed >= sizeof(buffer)) { printf("Warning: Output was truncated!\n"); } // Safe way to handle dynamic allocation if (needed > 0) { char* dynamic_buffer = malloc(needed + 1); if (dynamic_buffer) { sprintf(dynamic_buffer, "Data: %s", long_text); printf("\nDynamic buffer (%d bytes): %s\n", needed + 1, dynamic_buffer); free(dynamic_buffer); } } return 0; } 3. asprintf() - Allocating Formatted String (GNU extension)
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> int main() { char* result; char* name = "Bob"; int score = 95; char grade = 'A'; // asprintf allocates exactly the right amount of memory int chars = asprintf(&result, "Student: %s, Score: %d, Grade: %c", name, score, grade); if (chars >= 0) { printf("Formatted string: %s\n", result); printf("Length: %d\n", chars); free(result); // Must free when done } // Building complex strings char* parts[] = {"Hello", "World", "from", "asprintf"}; char* message; int total = asprintf(&message, "%s %s %s %s!", parts[0], parts[1], parts[2], parts[3]); if (total >= 0) { printf("\n%s\n", message); free(message); } return 0; } Advanced Formatting Techniques
1. Dynamic Width and Precision
#include <stdio.h> int main() { int width = 10; int precision = 3; double value = 123.456789; printf("=== Dynamic Width and Precision ===\n\n"); // Using * for dynamic width/precision printf("Dynamic width (%d): [%*d]\n", width, width, 42); printf("Dynamic precision (%d): [%.*f]\n", precision, precision, value); printf("Dynamic both (%d,%d): [%*.*f]\n", width, precision, width, precision, value); // Table formatting with dynamic widths char* items[] = {"Apple", "Banana", "Cherry", "Date"}; int prices[] = {50, 35, 75, 120}; int quantities[] = {10, 20, 15, 8}; printf("\n%-*s %*s %*s %*s\n", 10, "Item", 8, "Price", 10, "Quantity", 12, "Total"); for (int i = 0; i < 4; i++) { int total = prices[i] * quantities[i]; printf("%-*s %*d %*d %*d\n", 10, items[i], 8, prices[i], 10, quantities[i], 12, total); } return 0; } Output:
=== Dynamic Width and Precision === Dynamic width (10): [ 42] Dynamic precision (3): [123.457] Dynamic both (10,3): [ 123.457] Item Price Quantity Total Apple 50 10 500 Banana 35 20 700 Cherry 75 15 1125 Date 120 8 960
2. Field Width from Variable
#include <stdio.h> int main() { int data[] = {5, 50, 500, 5000, 50000}; int max_width = 0; // Find maximum width needed for (int i = 0; i < 5; i++) { int width = snprintf(NULL, 0, "%d", data[i]); if (width > max_width) max_width = width; } printf("=== Dynamic Column Widths ===\n"); printf("Maximum width needed: %d\n\n", max_width); printf("%-*s %-*s %-*s\n", max_width, "Index", max_width, "Value", max_width, "Square"); for (int i = 0; i < 5; i++) { printf("%-*d %-*d %-*d\n", max_width, i, max_width, data[i], max_width, data[i] * data[i]); } return 0; } 3. Scientific and Engineering Notation
#include <stdio.h> #include <math.h> int main() { double numbers[] = {0.000123, 0.0123, 1.23, 123, 12300, 1230000}; printf("=== Scientific and Engineering Notation ===\n\n"); printf("%-15s %-15s %-15s %-15s\n", "Number", "Fixed", "Scientific", "Engineering"); for (int i = 0; i < 6; i++) { double n = numbers[i]; printf("%-15g ", n); printf("%-15.3f ", n); printf("%-15.3e ", n); // Engineering notation (power of 3 exponent) int exp; double mantissa = frexp(n, &exp); exp = (exp - 1) / 3 * 3; printf("%-15.3fe%+03d\n", n / pow(10, exp), exp); } return 0; } Formatting Different Data Types
1. Hexadecimal and Binary Formatting
#include <stdio.h> void print_binary(unsigned int num) { printf("0b"); for (int i = 31; i >= 0; i--) { printf("%d", (num >> i) & 1); if (i % 4 == 0 && i > 0) printf("_"); } } int main() { unsigned int values[] = {0, 1, 42, 255, 1024, 0xABCD}; printf("=== Hexadecimal and Binary Formatting ===\n\n"); printf("%-10s %-12s %-12s %-35s\n", "Decimal", "Hex", "Octal", "Binary"); for (int i = 0; i < 6; i++) { printf("%-10u ", values[i]); printf("0x%-8X ", values[i]); printf("%-10o ", values[i]); print_binary(values[i]); printf("\n"); } // Memory address formatting int x = 42; int* ptr = &x; printf("\nPointer formatting:\n"); printf(" %%p: %p\n", ptr); printf(" %%#x: %#x\n", (unsigned long)ptr); printf(" %%#X: %#X\n", (unsigned long)ptr); return 0; } 2. Date and Time Formatting
#include <stdio.h> #include <time.h> int main() { time_t now = time(NULL); struct tm* tm_info = localtime(&now); char buffer[100]; printf("=== Date and Time Formatting ===\n\n"); // Manual formatting printf("Manual: %04d-%02d-%02d %02d:%02d:%02d\n", 1900 + tm_info->tm_year, tm_info->tm_mon + 1, tm_info->tm_mday, tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec); // Using strftime strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info); printf("strftime: %s\n", buffer); strftime(buffer, sizeof(buffer), "%A, %B %d, %Y", tm_info); printf("Long date: %s\n", buffer); strftime(buffer, sizeof(buffer), "%I:%M:%S %p", tm_info); printf("12-hour time: %s\n", buffer); // Custom formatting with leading zeros printf("\nCustom formats:\n"); printf(" YYYYMMDD: %04d%02d%02d\n", 1900 + tm_info->tm_year, tm_info->tm_mon + 1, tm_info->tm_mday); printf(" HHMMSS: %02d%02d%02d\n", tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec); return 0; } 3. Currency Formatting
#include <stdio.h> #include <locale.h> int main() { // Set locale for currency formatting setlocale(LC_ALL, "en_US.UTF-8"); double amounts[] = {1234.56, 0.99, 1000000.00, -42.50}; char* currencies[] = {"USD", "EUR", "GBP", "JPY"}; printf("=== Currency Formatting ===\n\n"); printf("%-10s %-15s %-15s %-15s\n", "Currency", "Amount", "Formatted", "Accounting"); for (int i = 0; i < 4; i++) { double amt = amounts[i]; printf("%-10s ", currencies[i]); printf("$%-14.2f ", amt); // Standard formatting if (amt >= 0) { printf("$%'.2f ", amt); } else { printf("($%'0.2f) ", -amt); } // Accounting format if (amt >= 0) { printf(" %'10.2f ", amt); } else { printf("(%'9.2f) ", -amt); } printf("\n"); } return 0; } Complex String Building
1. Building JSON Strings
#include <stdio.h> #include <string.h> typedef struct { char name[50]; int age; char city[50]; double salary; } Person; char* person_to_json(Person* p, char* buffer, size_t size) { snprintf(buffer, size, "{\n" " \"name\": \"%s\",\n" " \"age\": %d,\n" " \"city\": \"%s\",\n" " \"salary\": %.2f\n" "}", p->name, p->age, p->city, p->salary); return buffer; } int main() { Person people[] = { {"Alice Smith", 30, "New York", 75000.00}, {"Bob Johnson", 25, "Los Angeles", 65000.50}, {"Charlie Brown", 35, "Chicago", 82000.75} }; char buffer[500]; printf("=== JSON Formatting ===\n\n"); for (int i = 0; i < 3; i++) { printf("%s\n", person_to_json(&people[i], buffer, sizeof(buffer))); if (i < 2) printf("\n"); } // Build JSON array char json_array[2000] = "[\n"; for (int i = 0; i < 3; i++) { person_to_json(&people[i], buffer, sizeof(buffer)); strcat(json_array, buffer); if (i < 2) strcat(json_array, ",\n"); } strcat(json_array, "\n]"); printf("\nJSON Array:\n%s\n", json_array); return 0; } 2. Building CSV Strings
#include <stdio.h> #define MAX_FIELDS 10 typedef struct { char* fields[MAX_FIELDS]; int field_count; } CSVRecord; char* csv_escape(char* dest, const char* src, size_t dest_size) { int j = 0; for (int i = 0; src[i] != '\0' && j < dest_size - 1; i++) { if (src[i] == '"' || src[i] == ',' || src[i] == '\n') { if (j < dest_size - 2) { dest[j++] = '"'; dest[j++] = src[i]; dest[j++] = '"'; } } else { dest[j++] = src[i]; } } dest[j] = '\0'; return dest; } int main() { CSVRecord records[] = { {{"John Doe", "30", "New York", "75000"}, 4}, {{"Jane Smith", "28", "Los Angeles", "82000"}, 4}, {{"Bob \"The Builder\" Johnson", "35", "Chicago, IL", "65000"}, 4} }; char buffer[256]; char escaped[256]; printf("=== CSV Formatting ===\n\n"); // Header printf("Name,Age,City,Salary\n"); // Records for (int i = 0; i < 3; i++) { for (int j = 0; j < records[i].field_count; j++) { csv_escape(escaped, records[i].fields[j], sizeof(escaped)); printf("%s", escaped); if (j < records[i].field_count - 1) { printf(","); } } printf("\n"); } return 0; } 3. Building SQL Queries
#include <stdio.h> #include <string.h> typedef struct { char column[50]; char value[100]; int is_string; } QueryCondition; void build_select_query(char* query, size_t size, const char* table, const char* columns[], int col_count, const QueryCondition* conditions, int cond_count) { char temp[1024]; int offset = 0; // SELECT clause offset += snprintf(query + offset, size - offset, "SELECT "); for (int i = 0; i < col_count; i++) { offset += snprintf(query + offset, size - offset, "%s", columns[i]); if (i < col_count - 1) { offset += snprintf(query + offset, size - offset, ", "); } } // FROM clause offset += snprintf(query + offset, size - offset, " FROM %s", table); // WHERE clause if (cond_count > 0) { offset += snprintf(query + offset, size - offset, " WHERE "); for (int i = 0; i < cond_count; i++) { if (conditions[i].is_string) { offset += snprintf(query + offset, size - offset, "%s = '%s'", conditions[i].column, conditions[i].value); } else { offset += snprintf(query + offset, size - offset, "%s = %s", conditions[i].column, conditions[i].value); } if (i < cond_count - 1) { offset += snprintf(query + offset, size - offset, " AND "); } } } offset += snprintf(query + offset, size - offset, ";"); } int main() { const char* columns[] = {"id", "name", "age", "city"}; QueryCondition conditions[] = { {"age", "30", 0}, {"city", "New York", 1} }; char query[1024]; build_select_query(query, sizeof(query), "users", columns, 4, conditions, 2); printf("=== SQL Query Building ===\n\n"); printf("Generated query:\n%s\n", query); return 0; } Performance Optimization
1. Comparing Formatting Methods
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define ITERATIONS 1000000 #define BUFFER_SIZE 100 void benchmark_sprintf() { char buffer[BUFFER_SIZE]; for (int i = 0; i < ITERATIONS; i++) { sprintf(buffer, "Value: %d, Pi: %.2f", i, 3.14159); } } void benchmark_snprintf() { char buffer[BUFFER_SIZE]; for (int i = 0; i < ITERATIONS; i++) { snprintf(buffer, BUFFER_SIZE, "Value: %d, Pi: %.2f", i, 3.14159); } } void benchmark_asprintf() { char* buffer; for (int i = 0; i < ITERATIONS; i++) { asprintf(&buffer, "Value: %d, Pi: %.2f", i, 3.14159); free(buffer); } } void benchmark_manual() { char buffer[BUFFER_SIZE]; for (int i = 0; i < ITERATIONS; i++) { char* p = buffer; p += sprintf(p, "Value: "); p += sprintf(p, "%d", i); p += sprintf(p, ", Pi: "); p += sprintf(p, "%.2f", 3.14159); *p = '\0'; } } double measure_time(void (*func)()) { clock_t start = clock(); func(); clock_t end = clock(); return ((double)(end - start)) / CLOCKS_PER_SEC; } int main() { printf("=== Performance Comparison ===\n"); printf("Iterations: %d\n\n", ITERATIONS); printf("sprintf(): %.3f seconds\n", measure_time(benchmark_sprintf)); printf("snprintf(): %.3f seconds\n", measure_time(benchmark_snprintf)); printf("asprintf(): %.3f seconds\n", measure_time(benchmark_asprintf)); printf("Manual concat: %.3f seconds\n", measure_time(benchmark_manual)); return 0; } 2. Optimizing Repeated Formatting
#include <stdio.h> // Pre-computed format string const char* format_template = "User: %-20s | Age: %3d | Score: %6.2f\n"; void print_user(const char* name, int age, double score) { printf(format_template, name, age, score); } int main() { printf("=== Optimized Formatting ===\n\n"); // Using pre-computed format string print_user("Alice", 25, 95.5); print_user("Bob", 30, 87.3); print_user("Charlie", 28, 91.8); // Format string can be reused char buffer[1000]; int pos = 0; pos += sprintf(buffer + pos, "Data:\n"); for (int i = 0; i < 5; i++) { pos += sprintf(buffer + pos, " Item %d: %d\n", i, i * i); } printf("\n%s", buffer); return 0; } Error Handling in String Formatting
1. Checking Return Values
#include <stdio.h> #include <errno.h> int safe_sprintf(char* buffer, size_t size, const char* format, ...) { va_list args; va_start(args, format); int result = vsnprintf(buffer, size, format, args); va_end(args); if (result < 0) { // Encoding error return -1; } if ((size_t)result >= size) { // Truncation occurred errno = ENOSPC; return -1; } return result; } int main() { char buffer[10]; int result; printf("=== Error Handling ===\n\n"); // Successful formatting result = safe_sprintf(buffer, sizeof(buffer), "Hi"); if (result >= 0) { printf("Success: '%s' (%d chars)\n", buffer, result); } // Truncation result = safe_sprintf(buffer, sizeof(buffer), "This is a very long string"); if (result < 0 && errno == ENOSPC) { printf("Truncation detected: buffer too small\n"); } // Multiple calls with error checking char* parts[] = {"Part1", "Part2", "Part3", "Part4"}; char full[30]; int offset = 0; for (int i = 0; i < 4; i++) { int written = safe_sprintf(full + offset, sizeof(full) - offset, "%s%s", i == 0 ? "" : "-", parts[i]); if (written < 0) { printf("Error formatting at part %d\n", i); break; } offset += written; } if (offset < sizeof(full)) { printf("Result: %s\n", full); } return 0; } Locale-Specific Formatting
#include <stdio.h> #include <locale.h> int main() { double number = 1234567.89; printf("=== Locale-Specific Formatting ===\n\n"); // Default locale printf("Default locale: %'.2f\n", number); // Try different locales const char* locales[] = {"en_US.UTF-8", "de_DE.UTF-8", "fr_FR.UTF-8", "es_ES.UTF-8"}; for (int i = 0; i < 4; i++) { if (setlocale(LC_ALL, locales[i]) != NULL) { printf("%s: %'.2f\n", locales[i], number); } else { printf("%s: not available\n", locales[i]); } } return 0; } Best Practices Summary
Do's and Don'ts
// ✅ DO: Use snprintf() for safety char buffer[100]; snprintf(buffer, sizeof(buffer), "Value: %d", x); // ✅ DO: Check return values int written = snprintf(buffer, sizeof(buffer), "%s", long_string); if (written >= sizeof(buffer)) { // Handle truncation } // ✅ DO: Use appropriate format specifiers printf("%zu", sizeof(int)); // size_t printf("%td", ptr_diff); // ptrdiff_t printf("%" PRId64, int64_val); // int64_t (inttypes.h) // ✅ DO: Limit string width to prevent overflow printf("%.100s", user_input); // Limit to 100 chars // ✅ DO: Use asprintf() for dynamic allocation char* result; asprintf(&result, "Complex %s %d", str, num); // Use result free(result); // ❌ DON'T: Use sprintf without bounds checking sprintf(buffer, "%s", long_string); // Buffer overflow risk! // ❌ DON'T: Pass user input directly as format string printf(user_input); // Format string vulnerability! // Use: printf("%s", user_input); // ❌ DON'T: Assume buffer is large enough char small[10]; sprintf(small, "This is way too long"); // Overflow! // ❌ DON'T: Ignore return values snprintf(buffer, sizeof(buffer), "%d", x); // Check if it succeeded! // ❌ DON'T: Mix up format specifiers printf("%d", long_value); // Wrong specifier - undefined behavior! Format Specifier Quick Reference
| Type | Format | Example |
|---|---|---|
int | %d or %i | printf("%d", 42); |
unsigned int | %u | printf("%u", 42u); |
long | %ld | printf("%ld", 42L); |
long long | %lld | printf("%lld", 42LL); |
size_t | %zu | printf("%zu", sizeof(int)); |
float | %f | printf("%f", 3.14f); |
double | %f or %lf | printf("%lf", 3.14); |
char | %c | printf("%c", 'A'); |
char* | %s | printf("%s", "hello"); |
void* | %p | printf("%p", ptr); |
hex | %x or %X | printf("%x", 255); |
octal | %o | printf("%o", 255); |
Common Format Modifiers
| Modifier | Meaning | Example |
|---|---|---|
- | Left align | %-10s |
+ | Show sign | %+d |
| (space) | Space for positive | % d |
0 | Zero pad | %05d |
# | Alternate form | %#x |
* | Dynamic width | %*d |
. | Precision | %.2f |
Conclusion
String formatting in C is a powerful feature with many applications:
Key Functions
- printf() - Output to stdout
- sprintf() - Format to string
- snprintf() - Safe string formatting
- asprintf() - Dynamic allocation
- fprintf() - Format to file
Best Practices
- Always use snprintf() for safety
- Check return values for errors
- Limit string lengths for user input
- Never use user input as format string
- Use appropriate format specifiers
- Consider locale for internationalization
- Pre-allocate buffers for performance
Common Applications
- Logging and debugging
- Data serialization (JSON, CSV, XML)
- Report generation
- User interface output
- Network protocol formatting
Mastering string formatting is essential for creating robust, secure, and well-formatted output in C programs.
Complete C Programming Guide + Compilers Collection
1. C srand() Function – Understanding Seed Initialization
https://macronepal.com/understanding-the-c-srand-function
Explains how srand() initializes the pseudo-random number generator in C by setting a seed value. Using the same seed produces the same sequence, while time(NULL) gives different results each run.
2. C rand() Function Mechanics and Limitations
https://macronepal.com/c-rand-function-mechanics-and-limitations
Explains how rand() generates pseudo-random numbers between 0 and RAND_MAX, its deterministic nature, and limitations for security use cases.
3. C log() Function
https://macronepal.com/c-log-function-2
Covers natural logarithm calculation using <math.h> and its applications.
4. Mastering Date and Time in C
https://macronepal.com/mastering-date-and-time-in-c
Explains <time.h> functions like time(), clock(), difftime(), and struct tm.
5. Mastering time_t Type in C
https://macronepal.com/mastering-the-c-time_t-type-for-time-management
Explains time representation as seconds since Unix epoch and conversion functions.
6. C exp() Function
https://macronepal.com/c-exp-function-mechanics-and-implementation
Explains exponential function exp(x) and its scientific applications.
7. C log() Function (Alternate Guide)
https://macronepal.com/c-log-function
Comparison of log() and log10() with usage examples.
8. C log10() Function
https://macronepal.com/mastering-the-log10-function-in-c
Explains base-10 logarithm for engineering and scientific applications.
9. C tan() Function
https://macronepal.com/understanding-the-c-tan-function
Explains tangent function and radian-based calculations.
10. Random Numbers in C (Secure vs Predictable)
https://macronepal.com/mastering-c-random-numbers-for-secure-and-predictable-applications
Explains difference between rand() and secure randomness methods.
11. Free Online C Compiler
https://macronepal.com/free-online-c-code-compiler-2
Browser-based compiler for testing C programs instantly.
C Functions, Arguments, Parameters & Flow
Mastering Functions in C – Complete Guide
https://macronepal.com/c/mastering-functions-in-c-a-complete-guide/
Covers function structure, modular programming, and real-world usage.
Function Arguments in C
https://macronepal.com/c-function-arguments/
Explains how arguments are passed and used in function calls.
Function Parameters in C
https://macronepal.com/c-function-parameters/
Explains defining inputs for functions and matching them with arguments.
Function Declarations in C
https://macronepal.com/c-function-declarations-syntax-rules-and-best-practices/
Covers prototypes, syntax rules, and best practices.
Function Calls in C
https://macronepal.com/understanding-function-calls-in-c-syntax-mechanics-and-best-practices/
Explains execution flow and parameter handling during function calls.
Void Functions in C
https://macronepal.com/understanding-void-functions-in-c-syntax-patterns-and-best-practices/
Explains functions that do not return values.
Return Values in C
https://macronepal.com/c-return-values-mechanics-types-and-best-practices/
Explains different return types and how functions return results.
Pass-by-Value in C
https://macronepal.com/aws/understanding-pass-by-value-in-c-mechanics-implications-and-best-practices/
Explains how copies of variables are passed into functions.
Pass-by-Reference in C
https://macronepal.com/c/understanding-pass-by-reference-in-c-pointers-semantics-and-safe-practices/
Explains using pointers to modify original variables.
C strstr() Function
https://macronepal.com/aws/c-strstr-function/
Explains substring search inside strings in C.
C Preprocessor & Macros
https://macronepal.com/mastering-c-variadic-macros-for-flexible-debugging/
https://macronepal.com/mastering-the-stdc-macro-in-c/
https://macronepal.com/c-time-macro-mechanics-and-usage/
https://macronepal.com/understanding-the-c-date-macro/
https://macronepal.com/c-file-type/
https://macronepal.com/mastering-c-line-macro-for-debugging-and-diagnostics/
https://macronepal.com/mastering-predefined-macros-in-c/
https://macronepal.com/c-error-directive-mechanics-and-usage/
https://macronepal.com/understanding-the-c-pragma-directive/
https://macronepal.com/c-include-directive/
C Structures, Memory, Scope & Linkage
https://macronepal.com/mastering-structures-in-c/
https://macronepal.com/c-structure-declaration-mechanics-and-usage/
https://macronepal.com/c-structure-initialization-mechanics-and-best-practices/
https://macronepal.com/mastering-c-structure-member-access-for-reliable-data-handling/
https://macronepal.com/c-nested-structures/
https://macronepal.com/mastering-arrays-of-structures-in-c/
https://macronepal.com/c-structure-pointers-mechanics-and-implementation/
https://macronepal.com/understanding-c-structure-parameter-passing-mechanics/
https://macronepal.com/mastering-c-returning-structures-for-efficient-data-flow/
https://macronepal.com/c-self-referential-structures/
https://macronepal.com/mastering-structure-alignment-in-c/
https://macronepal.com/c-structure-padding-mechanics-and-optimization/
https://macronepal.com/understanding-c-flexible-array-members-mechanics-and-usage/
https://macronepal.com/mastering-c-anonymous-structures-for-flattened-data-layouts/
https://macronepal.com/c-unions/
https://macronepal.com/mastering-c-name-mangling-and-symbol-decoration/
https://macronepal.com/c-no-linkage-mechanics-and-scope-isolation/
https://macronepal.com/understanding-c-internal-linkage-mechanics-and-architecture/
C Scope, Storage Classes & Typedef
https://macronepal.com/mastering-function-prototype-scope-in-c/
https://macronepal.com/c-function-scope-mechanics-and-visibility/
https://macronepal.com/understanding-c-file-scope-mechanics-and-architecture/
https://macronepal.com/mastering-c-scope-rules-for-predictable-name-resolution/
https://macronepal.com/c-scope-rules/
https://macronepal.com/mastering-c-register-storage-class-for-historical-context-and-modern-alternatives/
https://macronepal.com/mastering-_thread_local-in-c/
https://macronepal.com/c-extern-storage-class-mechanics-and-usage/
https://macronepal.com/understanding-the-c-static-storage-class-mechanics-and-usage/
https://macronepal.com/c-auto-storage-class/
https://macronepal.com/c-typedef-with-pointers/
Extra Articles
https://macronepal.com/13757-2/
https://macronepal.com/13748-2/
https://macronepal.com/13747-2/
https://macronepal.com/13746-2/
https://macronepal.com/13745-2/
https://macronepal.com/13708-2/
https://macronepal.com/13707-2/
https://macronepal.com/13702-2/
Online Compilers
https://macronepal.com/free-html-online-code-compiler/
https://macronepal.com/free-online-python-code-compiler/
https://macronepal.com/free-online-python2-code-compiler/
https://macronepal.com/free-online-java-code-compiler/
https://macronepal.com/free-online-javascript-code-compiler/
https://macronepal.com/free-online-node-js-code-compiler/
https://macronepal.com/free-online-c-code-compiler/
https://macronepal.com/free-online-c-code-compiler-2/
https://macronepal.com/free-online-c-code-compiler-3/
https://macronepal.com/free-online-php-code-compiler/
https://macronepal.com/free-online-ruby-code-compiler/
https://macronepal.com/free-online-perl-code-compiler/
https://macronepal.com/free-online-lua-code-compiler/
https://macronepal.com/free-online-tcl-code-compiler/
https://macronepal.com/free-online-groovy-code-compiler/
https://macronepal.com/free-online-j-shell-code-compiler/
https://macronepal.com/free-online-haskell-code-compiler/
https://macronepal.com/free-online-scala-code-compiler/
https://macronepal.com/free-online-common-lisp-code-compiler/
https://macronepal.com/free-online-d-code-compiler/
https://macronepal.com/free-online-ada-code-compiler/
https://macronepal.com/free-erlang-code-compiler/
https://macronepal.com/free-online-assembly-code-compiler/
