Last active
December 22, 2015 17:09
-
-
Save soulmachine/6504651 to your computer and use it in GitHub Desktop.
FB interview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @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