Beispiele
Im folgenden Beispiel wird die Subroutine Mbtowc verwendet, um ein Zeichen im Mehrbytezeichencode in Breitzeichencode zu konvertieren:
main()
{
char *s;
wchar_t wc;
int n;
(void)setlocale(LC_ALL,"");
/*
** s points to the character string that needs to be
** converted to a wide character to be stored in wc.
*/
n = mbtowc(&wc, s, MB_CUR_MAX);
if (n == -1){
/* Error handle */
}
if (n == 0){
/* case of name pointing to null */
}
/*
** wc contains the process code for the multibyte character
** pointed to by s.
*/
}
Im folgenden Beispiel wird die Subroutine WKtomb verwendet, um ein Zeichen im Breitzeichencode in Mehrbytezeichencode zu konvertieren:
main()
{
char *s;
wchar_t wc;
int n;
(void)setlocale(LC_ALL,"");
/*
** s points to the character string that needs to be
** converted to a wide character to be stored in wc.
*/
n = mbtowc(&wc, s, MB_CUR_MAX);
if (n == -1){
/* Error handle */
}
if (n == 0){
/* case of name pointing to null */
}
/*
** wc contains the process code for the multibyte character
** pointed to by s.
*/
}
Im folgenden Beispiel wird die Subroutine Mblen verwendet, um die Bytelänge eines Zeichens im Mehrbytezeichencode zu ermitteln:
#include <stdlib.h>
#include <locale.h>
main
{
char *name = "h";
int n;
(void)setlocale(LC_ALL,"");
n = mblen(name, MB_CUR_MAX);
/*
** The count returned in n is the multibyte length.
** It is always less than or equal to the value of
** MB_CUR_MAX in stdlib.h
*/
if(n == -1){
/* Error Handling */
}
}
Im folgenden Beispiel wird eine vorherige Zeichenposition in einer Mehrbytezeichenfolge abgerufen. Wenn Sie die vorherige Zeichenposition ausgehend von einer aktuellen Zeichenposition (keine zufällige Byteposition) ermitteln müssen, gehen Sie den Puffer beginnend am Anfang durch. Verwenden Sie die Subroutine Mblen , bis die aktuelle Zeichenposition erreicht ist, und speichern Sie die vorherige Zeichenposition, um die erforderliche Zeichenposition zu erhalten.
char buf[]; /* contains the multibyte string */
char *cur, /* points to the current character position */
char *prev, /* points to previous multibyte character */
char *p; /* moving pointer */
/* initialize the buffer and pointers as needed */
/* loop through the buffer until the moving pointer reaches
** the current character position in the buffer, always
** saving the last character position in prev pointer */
p = prev = buf;
/* cur points to a valid character somewhere in buf */
while(p< cur){
prev = p;
if( (i=mblen(p, mbcurmax))<=0){
/* invalid multibyte character or null */
/* You can have a different error handling
** strategy */
p++; /* skip it */
}else {
p += i;
}
}
/* prev will point to the previous character position */
/* Note that if( prev == cur), then it means that there was
** no previous character. Also, if all bytes up to the
** current character are invalid, it will treat them as
** all valid single-byte characters and this may not be what
** you want. One may change this to handle another method of
** error recovery. */
Im folgenden Beispiel wird die Subroutine Mbstowcs verwendet, um eine Mehrbytezeichenfolge in eine breite Zeichenfolge zu konvertieren:
#include <stdlib.h>
#include <locale.h>
main()
{
char *s;
wchar_t *pwcs;
size_t retval, n;
(void)setlocale(LC_ALL, "");
n = strlen(s) + 1; /*string length + terminating null */
/* Allocate required wchar array */
pwcs = (wchar_t *)malloc(n * sizeof(wchar_t) );
retval = mbstowcs(pwcs, s, n);
if(retval == -1){
/* Error handle */
}
/*
** pwcs contains the wide character string.
*/
}
Das folgende Beispiel veranschaulicht die Probleme bei der Verwendung der Subroutine Mbstowcs in einem großen Datenblock für die Konvertierung in Breitzeichenformat. Wenn ein ungültiges Mehrbyte gefunden wird, gibt die Subroutine mbstowcs den Wert -1
zurück, gibt aber nicht an, wo der Fehler aufgetreten ist. Daher muss die Subroutine mbtowc wiederholt verwendet werden, um jeweils ein Zeichen in einen Breitzeichencode zu konvertieren.
Bei der Konvertierung von codierten Einzelbytezeichensätzen besteht keine Möglichkeit für partielle Mehrbyte. Bei der Konvertierung von codierten Mehrbytezeichensätzen werden jedoch partielle Mehrbytezeichen in einen Speicherpuffer kopiert. Beim nächsten Aufruf der Subroutine Lesen wird das partielle Mehrbyte dem Rest der Bytefolge vorangestellt.
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
char *curp, *cure;
int bytesread, bytestoconvert, leftover;
int invalid_multibyte, mbcnt, wcnt;
wchar_t *pwcs;
wchar_t wbuf[BUFSIZ+1];
char buf[BUFSIZ+1];
char savebuf[MB_LEN_MAX];
size_t mb_cur_max;
int fd;
/*
** MB_LEN_MAX specifies the system wide constant for
** the maximum number of bytes in a multibyte character.
*/
(void)setlocale(LC_ALL, "");
mb_cur_max = MB_CUR_MAX;
fd = open(argv[1], 0);
if(fd < 0){
/* error handle */
}
leftover = 0;
if(mb_cur_max==1){ /* Single byte code sets case */
for(;;){
bytesread = read(fd, buf, BUSIZ);
if(bytesread <= 0)
break;
mbstowcs(wbuf, buf, bytesread+1);
/* Process using the wide character buffer */
}
/* File processed ... */
exit(0); /* End of program */
}else{ /* Multibyte code sets */
leftover = 0;
for(;;) {
if(leftover)
strncpy(buf, savebuf ,leftover);
bytesread=read(fd,buf+leftover, BUFSIZ-leftover);
if(bytesread <= 0)
break;
buf[leftover+bytesread] = '\0';
/* Null terminate string */
invalid_multibyte = 0;
bytestoconvert = leftover+bytesread;
cure= buf+bytestoconvert;
leftover=0;
pwcs = wbuf;
/* Stop processing when invalid mbyte found. */
curp= buf;
for(;curp<cure;){
mbcnt = mbtowc(pwcs,curp, mb_cur_max);
if(mbcnt>0){
curp += mbcnt;
pwcs++;
continue;
}else{
/* More data needed on next read*/
if ( cure-curp<mb_cur_max){
leftover=cure-curp;
strncpy(savebuf,curp,leftover);
/* Null terminate before partial mbyte */
*curp=0;
break;
}else{
/*Invalid multibyte found */
invalid_multibyte =1;
break;
}
}
}
if(invalid_multibyte){ /*error handle */
}
/* Process the wide char buffer */
}
}
}
Im folgenden Beispiel werden die Subroutinen Wcstombs und WCSLEN verwendet, um eine breite Zeichenfolge in Mehrbyteformat zu konvertieren:
#include <stdlib.h>
#include <locale.h>
main()
{
wchar_t *pwcs; /* Source wide character string */
char *s; /* Destination multibyte character string */
size_t n;
size_t retval;
(void)setlocale(LC_ALL, "");
/*
** Calculate the maximum number of bytes needed to
** store the wide character buffer in multibyte form in the
** current code page and malloc() the appropriate storage,
** including the terminating null.
*/
s = (char *) malloc( wcslen(pwcs) * MB_CUR_MAX + 1 );
retval= wcstombs( s, pwcs, n);
if( retval == -1) {
/* Error handle */
/* s points to the multibyte character string. */
}