Home > Blockchain >  Split string based on different charnum reported in it for each value
Split string based on different charnum reported in it for each value

Time:04-30

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;
}
  • Related