C vsscanf function
last modified May 15, 2025
String parsing is a crucial skill in C programming, enabling you to extract data
from formatted strings efficiently. The vsscanf function provides
powerful string scanning capabilities with variable arguments. This tutorial
explains vsscanf in depth, covering its syntax, format specifiers,
and practical applications. Learn to parse complex string data safely and
effectively with comprehensive examples and best practices.
What Is vsscanf?
The vsscanf function is a variant of sscanf that
accepts a va_list argument instead of variable arguments. It reads
formatted input from a string, similar to scanf, but with the
flexibility of variable argument lists. This function is declared in
stdarg.h and is particularly useful when creating wrapper functions
for string parsing. Always validate input and buffer sizes to prevent security
vulnerabilities.
Basic vsscanf Syntax
The function prototype for vsscanf is:
int vsscanf(const char *str, const char *format, va_list arg);
Parameters:
str: The input string to parseformat: Format string specifying expected inputarg: Variable argument list (va_list)
The function returns the number of successfully matched and assigned input items.
A return value of EOF indicates a read error occurred before any
matching. Note that vsscanf doesn't modify the original string.
Simple vsscanf Example
This basic example demonstrates how to use vsscanf to parse integers
from a string.
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
void parse_numbers(const char *str, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int result = vsscanf(str, fmt, args);
printf("Parsed %d values\n", result);
va_end(args);
}
int main() {
const char *data = "10 20 30";
int a, b, c;
parse_numbers(data, "%d %d %d", &a, &b, &c);
printf("Values: %d, %d, %d\n", a, b, c);
return 0;
}
This example shows a wrapper function parse_numbers that uses
vsscanf to parse three integers from a string. The
va_start macro initializes the variable argument list, which is
then passed to vsscanf. After parsing, va_end cleans
up the argument list. The function returns the count of successfully parsed
values.
Parsing Different Data Types
vsscanf can handle various data types using appropriate format
specifiers. This example demonstrates parsing multiple data types from a string.
#include <stdio.h>
#include <stdarg.h>
void parse_data(const char *str, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int count = vsscanf(str, fmt, args);
printf("Successfully parsed %d items\n", count);
va_end(args);
}
int main() {
const char *input = "John 25 78.5 A";
char name[20];
int age;
float score;
char grade;
parse_data(input, "%19s %d %f %c", &name, &age, &score, &grade);
printf("Name: %s\nAge: %d\nScore: %.1f\nGrade: %c\n",
name, age, score, grade);
return 0;
}
This example parses a string containing a name (string), age (integer), score
(float), and grade (character). Note the use of %19s to prevent
buffer overflow by limiting string input to 19 characters plus the null
terminator. Always specify maximum widths for string inputs to ensure safety.
The function reports how many items were successfully parsed.
Advanced Format Specifiers
vsscanf supports advanced format specifiers for precise parsing.
This example demonstrates scanning with width specifiers and pattern matching.
#include <stdio.h>
#include <stdarg.h>
void advanced_parse(const char *str, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int result = vsscanf(str, fmt, args);
if (result == EOF) {
printf("Parsing failed\n");
} else {
printf("Matched %d items\n", result);
}
va_end(args);
}
int main() {
const char *log_entry = "[2023-05-15 14:30:45] ERROR: File not found";
int year, month, day, hour, min, sec;
char level[10], message[50];
advanced_parse(log_entry, "[%d-%d-%d %d:%d:%d] %9[^:]: %49[^\n]",
&year, &month, &day, &hour, &min, &sec, level, message);
printf("Date: %d-%02d-%02d\nTime: %02d:%02d:%02d\n"
"Level: %s\nMessage: %s\n",
year, month, day, hour, min, sec, level, message);
return 0;
}
This example parses a complex log entry format using advanced specifiers. The
%[^:] format matches all characters until a colon is encountered,
while %[^\n] matches until a newline. Width specifiers (%9
and %49) prevent buffer overflows. The function handles date, time,
log level, and message extraction in a single operation, demonstrating
vsscanf's powerful pattern matching capabilities.
Error Handling with vsscanf
Proper error handling is crucial when parsing input. This example shows how to
validate vsscanf results and handle parsing errors.
#include <stdio.h>
#include <stdarg.h>
#include <stdbool.h>
bool safe_parse(const char *str, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
int expected, actual;
// First count the expected number of conversions
for (expected = 0; fmt[expected]; ) {
if (fmt[expected++] == '%' && fmt[expected] != '%' &&
fmt[expected] != '*') {
expected++;
}
}
actual = vsscanf(str, fmt, args);
va_end(args);
return actual == expected;
}
int main() {
const char *good_input = "42 3.14 hello";
const char *bad_input = "42 not_a_float hello";
int num;
float f;
char str[20];
if (safe_parse(good_input, "%d %f %19s", &num, &f, str)) {
printf("Good parse: %d, %.2f, %s\n", num, f, str);
} else {
printf("Failed to parse good input\n");
}
if (safe_parse(bad_input, "%d %f %19s", &num, &f, str)) {
printf("Parsed bad input (unexpected)\n");
} else {
printf("Correctly rejected bad input\n");
}
return 0;
}
This example implements a safer parsing function that verifies the expected
number of conversions matches the actual count. The safe_parse
function first counts the format specifiers in the format string, then compares
this with vsscanf's return value. This approach helps detect
partial or failed parsing attempts. Always validate parsing results before using
the extracted values in your program.
Building a Custom Parser with vsscanf
vsscanf is excellent for creating custom parsers. This example shows
a configuration file parser using vsscanf.
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>
bool parse_config_line(const char *line, const char *key,
const char *fmt, void *value) {
char current_key[50];
va_list args;
// First try to match the key
if (vsscanf(line, " %49[^= \t] = %[^\n]", current_key, (char *)value) != 2) {
return false;
}
if (strcmp(current_key, key) != 0) {
return false;
}
// If format specified, parse the value properly
if (fmt) {
va_start(args, value);
int result = vsscanf((char *)value, fmt, args);
va_end(args);
return result == 1;
}
return true;
}
int main() {
const char *config = "width = 1024\nheight = 768\ntitle = My Application";
int width, height;
char title[50];
char *line = strtok((char *)config, "\n");
while (line) {
if (parse_config_line(line, "width", "%d", &width)) {
printf("Found width: %d\n", width);
}
else if (parse_config_line(line, "height", "%d", &height)) {
printf("Found height: %d\n", height);
}
else if (parse_config_line(line, "title", "%49[^\n]", title)) {
printf("Found title: %s\n", title);
}
line = strtok(NULL, "\n");
}
return 0;
}
This example demonstrates building a configuration file parser using
vsscanf. The parse_config_line function handles
key-value pairs separated by equals signs. It first extracts the key and value as
strings, then optionally parses the value according to a specified format. The
parser supports different data types and provides flexible configuration
handling. This approach can be extended to handle more complex file formats.
Best Practices for Using vsscanf
- Validate Input Length: Always check that input strings are properly terminated and within expected bounds.
- Use Width Specifiers: Prevent buffer overflows by specifying maximum widths for string conversions.
- Check Return Values: Verify the number of successfully parsed items matches expectations.
- Consider Alternatives: For complex parsing, consider using
strtokor regular expressions instead. - Handle Errors Gracefully: Provide meaningful error messages when parsing fails.
Source
This tutorial has explored the vsscanf function in depth, from
basic usage to advanced parsing techniques. Mastering vsscanf
enables you to create flexible and powerful string parsing routines in your C
programs. Remember to always prioritize safety when parsing untrusted input.
Author
List C Standard Library.