How to split some strings defined in a specific format:
[length relevant char number]name=value[length relevant char number]name=value[length relevant char number]name=value[length relevant char number]name=value
Is possible to split it with a regex or a simple C code?
Eg.
INPUT:
0010name=mario0013surname=rossi0006age=180014address=street
OUTPUT:
name=mario surname=rossi age=18 address=street
CodePudding user response:
Regular expressions aren't needed for this sort of parsing. Just take the 4-digit integer string, convert it into an int, and take that many more characters from the string. Repeat until you're at the end:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void split_string(const char *s) {
while (*s) {
char lenstr[5] = { 0 };
memcpy(lenstr, s, 4); // Extract the length
s = 4; // And advance past those digits
int len = strtol(lenstr, NULL, 10);
printf("%.*s%c", len, s, s[len] ? ' ' : '\n'); // print len characters
s = len; // and advance past them to the next element
}
}
int main(void) {
const char *input =
"0010name=mario0013surname=rossi0006age=180014address=street";
split_string(input);
return 0;
}
Compiled and run, prints out name=mario surname=rossi age=18 address=street
.
A version that reads the input from a file:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void split_file(FILE *in) {
while (1) {
char lenstr[5] = {0};
size_t n;
if ((n = fread(lenstr, 1, 4, in)) != 4) {
if ((n == 0 || (n == 1 && lenstr[0] == '\n')) &&
feof(in)) { // Done with input
break;
}
fprintf(stderr, "Failed to read length: %s\n",
feof(in) ? "Unexpected end of file" : strerror(errno));
exit(EXIT_FAILURE);
}
char *eol;
size_t len = strtoul(lenstr, &eol, 10);
if (*eol) { // Should be null
fputs("Invalid format!\n", stderr);
exit(EXIT_FAILURE);
}
char *field = malloc(len 1);
if (fread(field, 1, len, in) != len) {
fprintf(stderr, "Failed to read field: %s\n",
feof(in) ? "Unexpected end of file" : strerror(errno));
exit(EXIT_FAILURE);
}
field[len] = 0;
printf("%s ", field);
free(field);
}
putchar('\n');
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: %s input-filename\n", argv[0]);
return EXIT_FAILURE;
}
FILE *in = fopen(argv[1], "r");
if (!in) {
fprintf(stderr, "Unable to open '%s': %s\n", argv[1], strerror(errno));
return EXIT_FAILURE;
}
split_file(in);
fclose(in);
return 0;
}