Created
January 15, 2018 14:41
-
-
Save iafisher/c9c4bd079083c21892093cc992025acc to your computer and use it in GitHub Desktop.
Read a string from stdin and convert it from UTF-8 to an encoding of your choice, and print the byte values
This file contains hidden or 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
#include <errno.h> | |
#include <iconv.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
void print_bytes(const char* prefix, const char* str, size_t len); | |
int main(int argc, char* argv[]) { | |
if (argc != 2) { | |
fputs("Usage: ./byteecho <encoding>\n", stderr); | |
return 1; | |
} | |
char* buffer = NULL; | |
ssize_t len; | |
size_t capacity = 0; | |
iconv_t cd = iconv_open(argv[1], "UTF-8"); | |
if (cd == (iconv_t) -1) { | |
if (errno == ENFILE) { | |
fputs("Error: too many files are open.\n", stderr); | |
} else if (errno == EINVAL) { | |
fprintf(stderr, "Error: converting to %s is not supported.\n", argv[1]); | |
} else if (errno == ENOMEM) { | |
fputs("Program error (out of memory)\n", stderr); | |
} else if (errno == EMFILE) { | |
fputs("Program error (process has max file descriptors open)\n", stderr); | |
} else { | |
fputs("Program error (unknown)", stderr); | |
} | |
return 2; | |
} | |
while ((len = getline(&buffer, &capacity, stdin)) != -1) { | |
/* Truncate the trailing newline. */ | |
buffer[--len] = '\0'; | |
/* A lot of extra space for bigger encoding. */ | |
size_t len_koi = len*5 + 3; | |
char* buffer_in_koi = malloc(len_koi); | |
/* Make copies for iconv. */ | |
char* buffer_end = buffer, *buffer_in_koi_end = buffer_in_koi; | |
size_t bytes_left = len, bytes_left_koi = len_koi; | |
size_t err = iconv(cd, &buffer_end, &bytes_left, &buffer_in_koi_end, &bytes_left_koi); | |
if (err == (size_t) -1) { | |
if (errno == EILSEQ) { | |
fputs("Error: invalid byte sequence in the input.\n", stderr); | |
} else if (errno == EINVAL) { | |
fputs("Error: incomplete byte sequence at end of input.\n", stderr); | |
} else if (errno == E2BIG) { | |
fputs("Program error (output buffer too small)\n", stderr); | |
} else if (errno == EBADF) { | |
fputs("Program error (invalid iconv_t handle)\n", stderr); | |
} else { | |
fputs("Program error (unknown)\n", stderr); | |
} | |
continue; | |
} | |
print_bytes("UTF-8", buffer, len); | |
print_bytes(argv[1], buffer_in_koi, len_koi - bytes_left_koi); | |
} | |
iconv_close(cd); | |
return 0; | |
} | |
void print_bytes(const char* encoding, const char* str, size_t len) { | |
unsigned int width_so_far = 3; | |
printf("In %s:\n ", encoding); | |
for (size_t i = 0; i < len; i++) { | |
if (width_so_far > 75) { | |
printf("\n "); | |
width_so_far = 3; | |
} | |
printf("%.2x ", (unsigned char)str[i]); | |
width_so_far += 3; | |
} | |
printf("\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment