2010-06-11 3 views
0

Voici ce que je suis en train de faire:comment convertir char * à uchar16 en JNI C++

typedef uint16_t uchar16_t; 
uchar16_t buf[32]; 
// buf will contain timezone information like GMT-6, Eastern Daylight Time, etc 

char * str = "Test"; 

for (int i = 0; i <= strlen(str); i++) 
    buf[i] = str[i]; 

Je suppose que ce n'est pas correct puisque uchar16_t contiendrait 2 octets et str contient 1 octet.

Qu'est-ce que je suis supposé faire?

+0

Formatez votre code la prochaine fois. –

+0

D'accord, merci Carl! –

+0

Aussi si vous créez un tampon de longueur fixe comme dans cet exemple, assurez-vous toujours de vérifier la longueur du tampon cible dans la boucle ou bien KABOOM si vous avez une chaîne source plus longue ... – humbagumba

Répondre

3

strlen? buf [32]? Essayer de détruire l'univers?

Vous souhaitez utiliser un flux wstringstream.

std::wstringstream lols; 
lols << "Test"; 
std::wstring cakes; 
lols >> cakes; 

Editer @ Commentaire: Vous ne devriez pas utiliser strlen parce que tout système de cordage performant permet des zéros intégrés et strlen est sérieusement lent. De plus, vous n'avez pas redimensionné votre buffer si nécessaire, donc si vous aviez une chaîne de taille> 31, vous auriez un buffer overflow. De plus, vous devrez (si vous avez dynamiquement dimensionné votre buffer) le libérer manuellement par la suite. Ces deux choses sont des échecs sérieux du système de cordes en C. Mon exemple de code permet à votre rédacteur de bibliothèque standard de faire tout le travail et d'éviter tous ces problèmes pour vous.

+0

Eh bien, j'apprends - comment vais-je apprendre à moins que vous me disiez pourquoi est-il tort de faire une strlen et ce qui pourrait être utilisé à la place de cette :) –

+1

@Sagar:.? pour des fins d'apprentissage, je suggère à la recherche dans cet article où Bjarne Stroustrup fait une analyse côte à côte de «la façon C» vs «la façon C++» de faire les choses (souvent la raison pour laquelle les gens pensent que C est plus rapide est simplement parce que vous omettez pour être correct): http://www2.research.att.com/~bs/new_learning.pdf – HostileFork

+0

@Hostile fourches: Merci, c'est vraiment une certaine information précieuse. –

0

Votre code fonctionnera, tant que str est ASCII; appeler strlen() dans la condition de boucle est probablement une mauvaise idée, cependant. Il pourrait être plus facile à utiliser simplement swprintf() si elle est disponible sur votre système:

uchar16_t buf[32]; 
char *str = "Test"; 
swprintf(buf, sizeof buf, "%s", str); 
+0

Carl, que puis-je utiliser à la place de strlen - est-ce que je vérifie pour '\ 0'? Mon code ne fonctionne pas - quand je l'imprime, il imprime tous les caractères vierges :( –

+0

@Sagar, ce qui imprime tous les caractères vides –

+0

@Sagar: Il est probablement vide –

0

Have a look here.

De plus, y a-t-il une bonne raison pour laquelle vous définissez votre propre type?

Si vous avez une (étroite) chaîne de char, vous ne pouvez pas le convertir en une chaîne wchar_t en définissant vos paramètres régionaux à « C » et en faisant passer la chaîne par mbstowcs(). Cela s'explique par le fait que le paramètre régional "C" spécifie un codage de caractères particulier, et que le codage du jeu de caractères d'exécution ne correspond pas , donc mbstowcs() pourrait mapper les caractères sur quelque chose d'inattendu ou même échouer (si le jeu de caractères d'exécution est arrivé à utiliser codages étaient incompatibles avec la structure de codage pour les paramètres régionaux C jeu de caractères.)

Ainsi, pour convertir char chaîne dans une chaîne plus large, vous avez à copier les caractères un par un dans un tableau de wchar_t. Si vous avez besoin de travailler avec Unicode ou utf-16 ou autre après cela, alors wcstombs() est ce que vous devriez regarder.

+0

Merci pour votre explication. Le typedef a été fait dans une bibliothèque existante, je dois donc l'utiliser 'tel quel'. –

+0

wcstombs génère un char * - J'ai besoin d'un uint16_t Donc, quand je fais cela, il me donne une erreur en disant "ne peut pas convertir de char * en uchar16_t *" –

1

C'est en fait OK si votre chaîne sera toujours ASCII. Pour le faire correctement, la fonction portable est mbstowcs, ce qui suppose que vous convertissez à partir des paramètres régionaux par défaut ou si vous êtes sous Windows, il existe des fonctions API qui vous permettent de spécifier explicitement la page de code source.