Skip to content

Instantly share code, notes, and snippets.

@iafisher
Created January 15, 2018 14:41
Show Gist options
  • Save iafisher/c9c4bd079083c21892093cc992025acc to your computer and use it in GitHub Desktop.
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
#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