Skip to content

Instantly share code, notes, and snippets.

@haxpor
Last active April 16, 2019 23:40
Show Gist options
  • Save haxpor/fded23df608d30b3d1dd2ba8cec7b82d to your computer and use it in GitHub Desktop.
Save haxpor/fded23df608d30b3d1dd2ba8cec7b82d to your computer and use it in GitHub Desktop.
Improved sgets implementation. Notice that if you allocate input string dynamically, you need to save original pointer to free it later.
lude <stdio.h>
#include <string.h>
#include <stdlib.h>
static char* sgets(char* dst_str, int dst_size, char** input_str)
{
// safety check, probably removed out in performance-centric code
if (input_str == NULL || *input_str == NULL)
return NULL;
// if end of the string from previous iteration(s)
if ((*input_str)[0] == '\0')
{
return NULL;
}
int size_count = 0;
// access value-only from input string
const char* input_str_val = *input_str;
for (int i = 0; i<dst_size; ++i)
{
char c = input_str_val[i];
if (c == '\n')
{
dst_str[i] = c;
dst_str[i+1] = '\0';
++size_count;
break;
}
else if (c == '\0')
{
dst_str[i] = c;
break;
}
else
{
dst_str[i] = c;
++size_count;
}
}
// update input str with number of bytes we've read
// effect address back to the caller
*input_str = (char*)((long)(*input_str) + size_count);
return dst_str;
}
int main(void)
{
#define STR "This is first line.\nThis is second line.\nThis is third line.\nThis is last line."
char* orig_str = malloc(sizeof(char) * (strlen(STR)+1));
printf("address of orig_str pointing to = %p\n" , orig_str);
char* opt_str = orig_str;
printf("address of opt_str pointing to = %p\n" , opt_str);
strncpy(opt_str, STR, strlen(STR)+1);
char line[256];
while (sgets(line, 256, &opt_str) != NULL)
{
printf("%s", line);
}
printf("address of orig_str pointing to after operation = %p (should stay the same)\n" , orig_str);
printf("address of opt_str pointing to after operation = %p (should changed)\n" , opt_str);
free(orig_str);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment