- 论坛徽章:
- 5
|
回复 8# tjf258 - #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <iconv.h>
- #include <stdlib.h>
- /*
- * For state-dependent encodings, changes the state of the conversion
- * descriptor to initial shift state. Also, outputs the byte sequence
- * to change the state to initial state.
- * This code is assuming the iconv call for initializing the state
- * won't fail due to lack of space in the output buffer.
- */
- #define INIT_SHIFT_STATE(cd, fptr, ileft, tptr, oleft) \
- { \
- fptr = NULL; \
- ileft = 0; \
- tptr = to; \
- oleft = BUFSIZ; \
- (void) iconv(cd, &fptr, &ileft, &tptr, &oleft); \
- (void) fwrite(to, 1, BUFSIZ - oleft, stdout); \
- }
- int
- main(int argc, char **argv)
- {
- iconv_t cd;
- char from[BUFSIZ], to[BUFSIZ];
- char *from_code, *to_code;
- char *tptr;
- const char *fptr;
- size_t ileft, oleft, num, ret;
- if (argc != 3) {
- (void) fprintf(stderr,
- "Usage: %s from_codeset to_codeset\\n", argv[0]);
- return (1);
- }
- from_code = argv[1];
- to_code = argv[2];
- cd = iconv_open((const char *)to_code, (const char *)from_code);
- if (cd == (iconv_t)-1) {
- /*
- * iconv_open failed
- */
- (void) fprintf(stderr,
- "iconv_open(%s, %s) failed\\n", to_code, from_code);
- return (1);
- }
- ileft = 0;
- while ((ileft +=
- (num = fread(from + ileft, 1, BUFSIZ - ileft, stdin))) >; 0) {
- if (num == 0) {
- /*
- * Input buffer still contains incomplete character
- * or sequence. However, no more input character.
- */
- /*
- * Initializes the conversion descriptor and outputs
- * the sequence to change the state to initial state.
- */
- INIT_SHIFT_STATE(cd, fptr, ileft, tptr, oleft);
- (void) iconv_close(cd);
- (void) fprintf(stderr, "Conversion error\\n");
- return (1);
- }
- fptr = from;
- for (;;) {
- tptr = to;
- oleft = BUFSIZ;
- ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
- if (ret != (size_t)-1) {
- /*
- * iconv succeeded
- */
- /*
- * Outputs converted characters
- */
- (void) fwrite(to, 1, BUFSIZ - oleft, stdout);
- break;
- }
- /*
- * iconv failed
- */
- if (errno == EINVAL) {
- /*
- * Incomplete character or shift sequence
- */
- /*
- * Outputs converted characters
- */
- (void) fwrite(to, 1, BUFSIZ - oleft, stdout);
- /*
- * Copies remaining characters in input buffer
- * to the top of the input buffer.
- */
- (void) memmove(from, fptr, ileft);
- /*
- * Tries to fill input buffer from stdin
- */
- break;
- } else if (errno == E2BIG) {
- /*
- * Lack of space in output buffer
- */
- /*
- * Outputs converted characters
- */
- (void) fwrite(to, 1, BUFSIZ - oleft, stdout);
- /*
- * Tries to convert remaining characters in
- * input buffer with emptied output buffer
- */
- continue;
- } else if (errno == EILSEQ) {
- /*
- * Illegal character or shift sequence
- */
- /*
- * Outputs converted characters
- */
- (void) fwrite(to, 1, BUFSIZ - oleft, stdout);
- /*
- * Initializes the conversion descriptor and
- * outputs the sequence to change the state to
- * initial state.
- */
- INIT_SHIFT_STATE(cd, fptr, ileft, tptr, oleft);
- (void) iconv_close(cd);
- (void) fprintf(stderr,
- "Illegal character or sequence\\n");
- return (1);
- } else if (errno == EBADF) {
- /*
- * Invalid conversion descriptor.
- * Actually, this shouldn't happen here.
- */
- (void) fprintf(stderr, "Conversion error\\n");
- return (1);
- } else {
- /*
- * This errno is not defined
- */
- (void) fprintf(stderr, "iconv error\\n");
- return (1);
- }
- }
- }
- /*
- * Initializes the conversion descriptor and outputs
- * the sequence to change the state to initial state.
- */
- INIT_SHIFT_STATE(cd, fptr, ileft, tptr, oleft);
- (void) iconv_close(cd);
- return (0);
- }
复制代码 |
|