-
Notifications
You must be signed in to change notification settings - Fork 0
Examples
Pablo R. edited this page Sep 29, 2025
·
2 revisions
This directory contains practical examples demonstrating STRAP's capabilities.
- readline_example.c - Safe line reading and trimming
- join_example.c - String joining with arrays and varargs
- Log File Parser - Parsing and processing log files
- Configuration Builder - Dynamically building configuration files
- Performance Benchmarking - Measuring and comparing performance of string operations
- Template Engine - Simple template processing engine
- CSV Parser - Parsing CSV files with STRAP utilities
- Error Handling and Robust Programming - Using STRAP's unified error reporting
- Arena Allocator for Temporary Strings - Efficient memory management for temporary allocations
- Locale-Aware String Operations - Unicode and locale-aware string processing
- Timezone-Aware Time Formatting - Working with timezones and ISO 8601
- Advanced String Replacement - Template processing and text transformation
#include <stdio.h>
#include <string.h>
#include "strap.h"
typedef struct {
char *timestamp;
char *level;
char *message;
} LogEntry;
LogEntry parse_log_line(const char *line) {
LogEntry entry = {0};
// Split by spaces (simplified parser)
const char *parts[3];
// ... parsing logic using strtrim and custom splitting
return entry;
}
int main(void) {
FILE *logfile = fopen("app.log", "r");
if (!logfile) return 1;
char *line;
while ((line = afgets(logfile)) != NULL) {
char *trimmed = strtrim(line);
if (strlen(trimmed) > 0) {
LogEntry entry = parse_log_line(trimmed);
printf("[%s] %s: %s\n", entry.timestamp, entry.level, entry.message);
// ... cleanup entry fields
}
free(line);
free(trimmed);
}
fclose(logfile);
return 0;
}
#include <stdio.h>
#include "strap.h"
char *build_database_url(const char *host, int port, const char *dbname) {
char port_str[16];
snprintf(port_str, sizeof(port_str), "%d", port);
return strjoin_va("", "postgresql://", host, ":", port_str, "/", dbname, NULL);
}
char *build_config_section(const char *section, const char **keys, const char **values, size_t count) {
char *header = strjoin_va("", "[", section, "]\n", NULL);
char *body = strdup("");
for (size_t i = 0; i < count; i++) {
char *old_body = body;
char *line = strjoin_va("", keys[i], " = ", values[i], "\n", NULL);
body = strjoin_va("", old_body, line, NULL);
free(old_body);
free(line);
}
char *result = strjoin_va("", header, body, "\n", NULL);
free(header);
free(body);
return result;
}
int main(void) {
// Database configuration
char *db_url = build_database_url("localhost", 5432, "myapp");
printf("Database URL: %s\n", db_url);
free(db_url);
// INI-style configuration
const char *keys[] = {"host", "port", "ssl"};
const char *values[] = {"localhost", "5432", "true"};
char *config = build_config_section("database", keys, values, 3);
printf("Config section:\n%s", config);
free(config);
return 0;
}
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "strap.h"
void benchmark_string_operations(void) {
struct timeval start, end, diff;
const int iterations = 100000;
printf("Benchmarking string operations (%d iterations)\n", iterations);
// Benchmark strjoin
gettimeofday(&start, NULL);
for (int i = 0; i < iterations; i++) {
const char *parts[] = {"hello", "world", "test", "string"};
char *result = strjoin(parts, 4, " ");
free(result);
}
gettimeofday(&end, NULL);
diff = timeval_sub(end, start);
printf("strjoin: %.6f seconds (%.2f ops/sec)\n",
timeval_to_seconds(diff), iterations / timeval_to_seconds(diff));
// Benchmark strtrim
gettimeofday(&start, NULL);
for (int i = 0; i < iterations; i++) {
char *result = strtrim(" test string with whitespace ");
free(result);
}
gettimeofday(&end, NULL);
diff = timeval_sub(end, start);
printf("strtrim: %.6f seconds (%.2f ops/sec)\n",
timeval_to_seconds(diff), iterations / timeval_to_seconds(diff));
// Benchmark strtrim_inplace
char test_buffer[100];
gettimeofday(&start, NULL);
for (int i = 0; i < iterations; i++) {
strcpy(test_buffer, " test string with whitespace ");
strtrim_inplace(test_buffer);
}
gettimeofday(&end, NULL);
diff = timeval_sub(end, start);
printf("strtrim_inplace: %.6f seconds (%.2f ops/sec)\n",
timeval_to_seconds(diff), iterations / timeval_to_seconds(diff));
}
int main(void) {
benchmark_string_operations();
return 0;
}
#include <stdio.h>
#include <string.h>
#include "strap.h"
char *simple_template(const char *template, const char *name, const char *value) {
// Very simple template engine: replace {{name}} with value
char *placeholder = strjoin_va("", "{{", name, "}}", NULL);
// Find and replace (simplified - would need proper implementation)
char *result = strdup(template);
char *pos = strstr(result, placeholder);
if (pos) {
// Replace logic would go here
// For demo, just return template + value
free(result);
result = strjoin_va(" ", template, "->", value, NULL);
}
free(placeholder);
return result;
}
int main(void) {
const char *template = "Hello {{name}}, welcome to {{app}}!";
char *step1 = simple_template(template, "name", "Alice");
char *final = simple_template(step1, "app", "STRAP");
printf("Template result: %s\n", final);
free(step1);
free(final);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "strap.h"
// Simple CSV parser using STRAP utilities
void parse_csv_file(const char *filename) {
FILE *fp = fopen(filename, "r");
if (!fp) {
printf("Cannot open file: %s\n", filename);
return;
}
char *line;
int row = 0;
while ((line = afgets(fp)) != NULL) {
char *trimmed = strtrim(line);
if (strlen(trimmed) > 0) {
printf("Row %d: %s\n", row++, trimmed);
// Simple CSV field extraction (without proper escaping)
char *field_line = strdup(trimmed);
char *field = strtok(field_line, ",");
int col = 0;
while (field) {
char *trimmed_field = strtrim(field);
printf(" Column %d: '%s'\n", col++, trimmed_field);
free(trimmed_field);
field = strtok(NULL, ",");
}
free(field_line);
}
free(line);
free(trimmed);
}
fclose(fp);
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: %s <csv_file>\n", argv[0]);
return 1;
}
parse_csv_file(argv[1]);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include "strap.h"
void safe_string_processing(const char *input) {
// Attempt to trim the input
char *trimmed = strtrim(input);
if (!trimmed) {
fprintf(stderr, "Failed to trim string: %s\n", strap_error_string(strap_last_error()));
return;
}
// Check if string starts with expected prefix
if (strstartswith(trimmed, "ERROR")) {
fprintf(stderr, "Error message detected: %s\n", trimmed);
} else if (strendswith(trimmed, ".txt")) {
printf("Text file reference: %s\n", trimmed);
} else {
printf("Processed: %s\n", trimmed);
}
free(trimmed);
}
int main(void) {
safe_string_processing(" ERROR: File not found ");
safe_string_processing(" document.txt ");
safe_string_processing(" regular message ");
return 0;
}
#include <stdio.h>
#include "strap.h"
void process_with_arena(const char *base_path, const char *filename) {
// Create arena for temporary allocations
strap_arena_t *arena = strap_arena_create(2048);
if (!arena) {
fprintf(stderr, "Failed to create arena\n");
return;
}
// Build path using arena allocation
char *full_path = strjoin_va("/", base_path, filename, NULL);
if (!full_path) {
fprintf(stderr, "Failed to build path\n");
strap_arena_destroy(arena);
return;
}
// Read file content
FILE *fp = fopen(full_path, "r");
if (fp) {
size_t len;
char *content = afread(fp, &len);
fclose(fp);
if (content) {
// Process content (using regular malloc for result)
char *processed = strreplace(content, "\n", "\\n");
if (processed) {
printf("File %s content: %s\n", filename, processed);
free(processed);
}
free(content);
}
}
// All arena allocations are automatically freed
strap_arena_destroy(arena);
}
int main(void) {
process_with_arena("/tmp", "example.txt");
return 0;
}
#include <stdio.h>
#include <locale.h>
#include "strap.h"
void demonstrate_locale_features(void) {
// Set locale for proper Unicode handling
setlocale(LC_ALL, "en_US.UTF-8");
const char *test_strings[] = {
"HELLO World",
"café",
"naïve",
"MÜLLER"
};
for (size_t i = 0; i < sizeof(test_strings) / sizeof(test_strings[0]); i++) {
const char *original = test_strings[i];
// Convert to lowercase
char *lower = strtolower_locale(original, NULL);
if (lower) {
printf("'%s' -> '%s' (lowercase)\n", original, lower);
free(lower);
}
// Convert to uppercase
char *upper = strtoupper_locale(original, NULL);
if (upper) {
printf("'%s' -> '%s' (uppercase)\n", original, upper);
free(upper);
}
printf("\n");
}
// Demonstrate collation (locale-aware comparison)
const char *str1 = "café";
const char *str2 = "cafe";
int cmp = strcoll_locale(str1, str2, "fr_FR.UTF-8");
printf("In French collation: '%s' %s '%s'\n",
str1, cmp > 0 ? ">" : cmp < 0 ? "<" : "==", str2);
int cmp_case = strcasecmp_locale("Hello", "HELLO", NULL);
printf("Case-insensitive comparison: %d\n", cmp_case);
}
int main(void) {
demonstrate_locale_features();
return 0;
}
#include <stdio.h>
#include <sys/time.h>
#include "strap.h"
void demonstrate_time_features(void) {
// Current time
struct timeval now;
gettimeofday(&now, NULL);
// Format in different timezones
char iso_str[32];
// UTC
if (strap_time_format_iso8601(now, 0, iso_str, sizeof(iso_str)) == 0) {
printf("UTC: %s\n", iso_str);
}
// Eastern Time (UTC-5)
if (strap_time_format_iso8601(now, -300, iso_str, sizeof(iso_str)) == 0) {
printf("EST: %s\n", iso_str);
}
// Tokyo Time (UTC+9)
if (strap_time_format_iso8601(now, 540, iso_str, sizeof(iso_str)) == 0) {
printf("JST: %s\n", iso_str);
}
// Parse ISO 8601 string
const char *iso_input = "2023-12-25T15:30:45+02:00";
struct timeval parsed;
int offset;
if (strap_time_parse_iso8601(iso_input, &parsed, &offset) == 0) {
printf("Parsed '%s': offset=%d minutes\n", iso_input, offset);
// Convert offset to string
char tz_str[16];
if (strap_time_offset_to_string(offset, tz_str, sizeof(tz_str)) == 0) {
printf("Timezone string: %s\n", tz_str);
}
}
// Add minutes to time
struct timeval future = timeval_add_minutes(now, 90); // 1.5 hours later
double seconds_diff = timeval_to_seconds(timeval_sub(future, now));
printf("90 minutes = %.0f seconds\n", seconds_diff);
}
int main(void) {
demonstrate_time_features();
return 0;
}
#include <stdio.h>
#include "strap.h"
void demonstrate_string_replacement(void) {
const char *template = "Hello {{name}}, welcome to {{app}} version {{version}}!";
const char *placeholders[][2] = {
{"{{name}}", "Alice"},
{"{{app}}", "STRAP"},
{"{{version}}", "0.3.0"}
};
char *result = strdup(template);
if (!result) return;
// Replace each placeholder
for (size_t i = 0; i < sizeof(placeholders) / sizeof(placeholders[0]); i++) {
char *new_result = strreplace(result, placeholders[i][0], placeholders[i][1]);
if (new_result) {
free(result);
result = new_result;
} else {
fprintf(stderr, "Failed to replace %s\n", placeholders[i][0]);
free(result);
return;
}
}
printf("Template result: %s\n", result);
free(result);
// Demonstrate case conversion with replacement
const char *text = "The QUICK brown FOX jumps OVER the lazy DOG.";
char *normalized = strtolower_locale(text, "en_US.UTF-8");
if (normalized) {
printf("Normalized: %s\n", normalized);
free(normalized);
}
}
int main(void) {
demonstrate_string_replacement();
return 0;
}
To build any of these examples:
# Single example
gcc -I.. -L.. -o example example.c -lstrap
# All examples
cd examples
make # If you create a Makefile for examples
For testing the examples, you might want to create sample data files:
sample.log:
2023-01-01 10:00:00 INFO Application started
2023-01-01 10:00:01 DEBUG Loading configuration
2023-01-01 10:00:02 WARN Missing optional setting
2023-01-01 10:00:03 ERROR Database connection failed
sample.csv:
Name,Age,City
Alice,30,New York
Bob,25,Los Angeles
Charlie,35,Chicago
These examples demonstrate practical applications of STRAP's functionality in real-world scenarios.