下面的简单代码应该从标准输入读取一个宽字符并将其回显到标准输出,除了它SIGSEGV
在iconv()
调用时死亡。问题是——代码有什么问题?
#include <unistd.h> /* STDIN_FILENO */
#include <locale.h> /* LC_ALL, setlocale() */
#include <langinfo.h> /* nl_langinfo(), CODESET */
#include <wchar.h> /* wchar_t, putwchar() */
#include <iconv.h> /* iconv_t, iconv_open(), iconv(), iconv_close() */
#include <stdlib.h> /* malloc(), EXIT_SUCCESS */
int main(void) {
setlocale(LC_ALL, ""); // We initialize the locale
iconv_t converter = iconv_open("WCHAR_T", nl_langinfo(CODESET)); // We initialize a converter
wchar_t out; // We allocate memory for one wide char on stack
wchar_t* pOut = &out;
size_t outLeft = sizeof(wchar_t);
while(outLeft > 0) { // Until we've read one wide char...
char in; // We allocate memory for one byte on stack
char* pIn=∈
size_t inLeft = 1;
if(read(STDIN_FILENO, pIn, 1) == 0) break; // We read one byte from stdin to the buffer
iconv(&converter, &pIn, &inLeft, (char**)&pOut, &outLeft); // We feed the byte to the converter
}
iconv_close(converter); // We deinitialize a converter
putwchar(out); // We echo the wide char back to stdout
return EXIT_SUCCESS;
}
更新:根据@gsg 的回答进行以下更新后:
iconv(converter, &pIn, &inLeft, &pOut, &outLeft);
该代码不再抛出 SIGSEGV,而是out == L'\n'
针对任何非 ASCII 输入。