Skip to content

Instantly share code, notes, and snippets.

@soulmachine
Last active December 22, 2015 17:09
Show Gist options
  • Save soulmachine/6504651 to your computer and use it in GitHub Desktop.
Save soulmachine/6504651 to your computer and use it in GitHub Desktop.
FB interview
/**
* @file string_serialization.c
* compile, gcc -std=c99 string_serialization.c ...
*
* @author Frank Dai
* @email soulmachine@gmail
*/
#include <stdio.h>
#include <stdlib.h> /* for strtoll, ato */
#include <string.h>
#include <limits.h>
#include <assert.h>
typedef long long int64_t;
#define SEPARATOR '#'
/* length of 64-bit signed integer, i.e 9223372036854775807LL */
#define MAX_LEN 19
#define RADIX 10
/**
* convert int to string.
* @param[in] n number
* @param[out] s string
* @return the number of characters
*/
static int int_to_str(int64_t n, char s[MAX_LEN+1]) {
snprintf(s, MAX_LEN+1, "%lld", n);
}
/**
* convert string to int.
* @param[in] s a string begins with numbers
* @param[out] n address of an int
* @return the numbers of characters
*/
static int str_to_int(const char *s, int64_t *n) {
char *end;
*n = strtoll(s, &end, 10);
return end - s;
}
/**
* string format: "len1#str1str2", length befor separator character #,
* is the length of first string
*/
/**
* @brief concat
* @param[in] s1 the first string, primitive string
* @param[in] s2 another string, primitive string
* @param[out] s structured string
* @return a new allocated buffer which contains the concated string
*/
char* string_concat(const char *s1, const char *s2) {
char *result; /* the concated string */
int len1, len2; /* length of s1, s2 */
char len1_str[MAX_LEN + 1];
int len1_len; /* length of len_str */
if (s1 == NULL)
len1 = 0;
else
len1 = strlen(s1);
if (s2 == NULL)
len2 = 0;
else
len2 = strlen(s2);
len1_len = int_to_str(len1, len1_str);
result = (char*) calloc(len1_len + 1 + len1 + len2 + 1, sizeof(char));
strncpy(result, len1_str, len1_len);
result[len1_len] = SEPARATOR;
if (len1 > 0) {
strncpy(result + len1_len + 1, s1, len1);
}
if (len2 > 0) {
strncpy(result + len1_len + 1 + len1, s2, len2);
}
return result;
}
/**
* @brief split
* @param[in] s received string from remote machine, structured string
* @param[out] s1 the first string, primitive string
* @param[out] s2 another string, primitive string
* @return 0 if success, otherwise error code
*/
int string_split(const char *s, char **s1, char **s2) {
int len1, len2;
int len1_len; /* digits of len1 */
const int len = strlen(s);
if (len < 2) { /* malfunctioned string */
*s1 = NULL;
*s2 = NULL;
return -1;
}
len1_len = str_to_int(s, &len1);
len2 = strlen(s + len1_len + 1);
*s1 = (char*) calloc(len1 + 1, sizeof(char));
*s2 = (char*) calloc(len2 + 1, sizeof(char));
strncpy(*s1, s + len1_len + 1, len1);
strncpy(*s2, s + len1_len + 1 + len1, len2);
return 0;
}
void unit_tests() {
char s[MAX_LEN + 1];
int n;
int_to_str(LONG_LONG_MIN, s);
printf("%s\n", s);
str_to_int(s, &n);
printf("%lld\n", n);
int_to_str(LONG_LONG_MAX, s);
str_to_int(s, &n);
printf("%lld\n", n);
int_to_str(0, s);
str_to_int(s, &n);
printf("%lld\n", n);
str_to_int("0#abc", &n);
printf("%lld\n", n);
str_to_int("9223372036854775807#abc", &n);
printf("%lld\n", n);
}
void unit_tests1() {
char *s, *s1, *s2;
s = string_concat("a", "b");
string_split(s, &s1, &s2);
printf("%s %s %s\n", s, s1, s2);
free(s1);
free(s2);
free(s);
s = string_concat(NULL, "b");
string_split(s, &s1, &s2);
printf("%s %s %s\n", s, s1, s2);
free(s1);
free(s2);
free(s);
s = string_concat("", "b");
string_split(s, &s1, &s2);
printf("%s %s %s\n", s, s1, s2);
free(s1);
free(s2);
free(s);
s = string_concat("a", "");
string_split(s, &s1, &s2);
printf("%s %s %s\n", s, s1, s2);
free(s1);
free(s2);
free(s);
s = string_concat("a", NULL);
string_split(s, &s1, &s2);
printf("%s %s %s\n", s, s1, s2);
free(s1);
free(s2);
free(s);
s = string_concat(NULL, NULL);
string_split(s, &s1, &s2);
printf("%s %s %s\n", s, s1, s2);
free(s1);
free(s2);
free(s);
s = string_concat("", "");
string_split(s, &s1, &s2);
printf("%s %s %s\n", s, s1, s2);
free(s1);
free(s2);
free(s);
}
int main(void) {
//unit_tests();
unit_tests1();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment