caractères accentués

RocouRocou Membre
07:19 modifié dans API AppKit #1
Je récupère des données texte d'une base de données PostgreSQL. Quelque soit les outils que j'utilise, je récupère et affiche correctement les caractères accentués, sauf avec mon application Cocoa...

à  la place d'un "é" j'obtiens "é"
et pour un "è" j'obtiens "è"

J'ai bien essayé de manipuler mes NSString, sans succès. Que faut-il faire?

«1

Réponses

  • schlumschlum Membre
    07:19 modifié #2
    Problème d'encoding... Doit déjà  y avoir une tonne de sujets qui en parlent.
  • RocouRocou Membre
    07:19 modifié #3
    dans 1236081475:

    Problème d'encoding... Doit déjà  y avoir une tonne de sujets qui en parlent.

    Certes mais aucun ne répond à  ma question. Où alors quelque chose m'échappe, d'où ce sujet ouvert.
  • CeetixCeetix Membre
    07:19 modifié #4
    Comment retires-tu tes chaines de caractères?
  • schlumschlum Membre
    07:19 modifié #5
    C'est pourtant pas compliqué... "é" en UTF8, c'est C3 A9... qui donne en Mac Roman : é
    Tiens donc...

    Donc récupère tes chaà®nes en UTF-8, ça ira mieux.
  • RocouRocou Membre
    07:19 modifié #6
    dans 1236085617:

    Comment retires-tu tes chaines de caractères?


    Voici mon code:

    NSDictionary *leDico;

    PGSQLRecordset *rs = [connection open:query];
    if (rs != nil) {
    if (![rs isEOF])
    {
    NSInteger i=0;
    while (![rs isEOF])
    {
    leDico=[rs dictionaryFromRecord];
                [popClient addItemWithTitle:[leDico valueForKey:@nom]]; // c'est bien une NSString mais les caractères ne sont pas accentués

    //Association de l'identifiant PostgreSQL avec le titre du PopPup (nom du client)
    NSString *k=[leDico valueForKey:@id];
    NSInteger j=[k integerValue];

    NSMenu* popClientMenu = [popClient menu];
    [[popClientMenu itemAtIndex:i] setTag:j];

    i=i++;
    [rs moveNext];
    }   

    }

  • schlumschlum Membre
    07:19 modifié #7
    C'est dans la classe "PGSQLRecordset" qu'il y a le problème à  priori... Y a pas une méthode pour lui définir son encoding de travail ?
  • RocouRocou Membre
    07:19 modifié #8
    dans 1236087801:

    C'est dans la classe "PGSQLRecordset" qu'il y a le problème à  priori... Y a pas une méthode pour lui définir son encoding de travail ?

    Hélas non. Il faut donc que je les "traduise" à  la volée mais comment faire?
  • schlumschlum Membre
    mars 2009 modifié #9
    dans 1236090451:

    dans 1236087801:

    C'est dans la classe "PGSQLRecordset" qu'il y a le problème à  priori... Y a pas une méthode pour lui définir son encoding de travail ?

    Hélas non. Il faut donc que je les "traduise" à  la volée mais comment faire?


    - (NSString*)convert:(NSString*)str<br />{<br />	return [NSString stringWithUTF8String:(const char*)[[str dataUsingEncoding:NSMacOSRomanStringEncoding] bytes]];<br />}
    


    (non testé...)
  • RocouRocou Membre
    07:19 modifié #10
    dans 1236092845:

    - (NSString*)convert:(NSString*)str<br />{<br />	return [NSString stringWithUTF8String:(const char*)[[str dataUsingEncoding:NSMacOSRomanStringEncoding] bytes]];<br />}
    


    (non testé...)

    Je te remercie. Les caractères accentués s'affichent mais la fin de chaà®ne semble contenir un peu n'importe quoi.
    Ton code ne fait-il pas référence à  une chaà®ne C?
    Je récupère un NSString que je dois encoder pour récupérer un NSString "traduit".
  • schlumschlum Membre
    07:19 modifié #11
    Je suis fatigué... C'est n'importe quoi ce que j'ai mis...

    - (NSString*)convert:(NSString*)str<br />{<br />	return [NSString stringWithUTF8String:[str cStringUsingEncoding:NSMacOSRomanStringEncoding]];<br />}
    


    Pourquoi passer par un NSData, qu'est-ce qui m'est passé par la tête  :o
  • AliGatorAliGator Membre, Modérateur
    07:19 modifié #12
    Heu moi je trouvais ça une très bonne idée au contraire de passer par du NSData, pour une simple et bonne raison, c'est que l'avantage de récupérer les octets, et donc la NSData, c'est que tu as vraiment la représentation MacRoman octet par octet. Passer par une cString me ferait "peur" dans le sens où c'est pas garanti d'être lossless comme conversion/extraction !
  • BaardeBaarde Membre
    07:19 modifié #13
    Le problème, c'est qu'il n'y a pas de caractère NULL de fin de chaà®ne lorsqu'on récupère des octets de la chaà®ne de caractères.
    Si on veut quand même passé par un NSData :
    - (NSString *)convert:(NSString *)str<br />{<br />&nbsp; &nbsp; return [[[NSString alloc] initWithData:[str dataUsingEncoding:NSMacOSRomanStringEncoding] encoding:NSUTF8StringEncoding] autorelease];<br />}
    
  • schlumschlum Membre
    07:19 modifié #14
    dans 1236121082:

    Heu moi je trouvais ça une très bonne idée au contraire de passer par du NSData, pour une simple et bonne raison, c'est que l'avantage de récupérer les octets, et donc la NSData, c'est que tu as vraiment la représentation MacRoman octet par octet. Passer par une cString me ferait "peur" dans le sens où c'est pas garanti d'être lossless comme conversion/extraction !


    Quel est le problème avec "cStringUsingEncoding" ?
    C'est sûr que s'il y a un problème de lossyConversion, ça renvoie NULL, mais à  priori il ne devrait pas y avoir de problème avec les chaà®nes venant de base de données (sinon, c'est que c'est corrompu, et pour le coup, NULL est une réponse adéquate je trouve !).

    Sinon : "- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding allowLossyConversion:(BOOL)flag"
    Puis effectivement utiliser "initWithData:encoding:" (je cherchais hier le convenient constructor équivalent, mais ne l'ayant pas trouvé je me suis bêtement rabattu sur "stringWithUTF8String"  ::) )
  • RocouRocou Membre
    07:19 modifié #15
    dans 1236109269:


    - (NSString*)convert:(NSString*)str<br />{<br />	return [NSString stringWithUTF8String:[str cStringUsingEncoding:NSMacOSRomanStringEncoding]];<br />}
    



    :adios!:
    Merci, ouf.
    Merci à  tous.

    Cependant j'ai une question probablement très basique: je n'arrive pas à  appeler cette fonction.
    J'utilise directement le code NSString *chaineConvertie =[NSString stringWithUTF8String:leDico valueForKey:@&quot;nom&quot;] cStringUsingEncoding:NSMacOSRomanStringEncoding;. ça fonctionne évidemment très bien.

    Mais
    NSString chaineConvertie;
    [chaineConvertie convert:[leDico valueForKey:@nom]];

    ne passe pas à  la compilation. J'imagine que je dois créer une nouvelle classe et son instance mais cela me parait bien lourd.
  • BaardeBaarde Membre
    07:19 modifié #16
    Pour ma part, j'utiliserais une catégorie pour ajouter la méthode convert à  NSString.

    @interface NSString (MacOSRomanToUTF8Converting)<br />- (NSString *)convert;<br />@end<br /><br />@implementation NSString (MacOSRomanToUTF8Converting)<br />- (NSString *)convert {<br />&nbsp; &nbsp; return [NSString stringWithUTF8String:[self cStringUsingEncoding:NSMacOSRomanStringEncoding]];<br />}<br />@end
    


    Puis, il suffit d'utiliser l'écriture suivante :

    NSString *chaineConvertie = [[leDico valueForKey:@&quot;nom&quot;] convert];
    
  • RocouRocou Membre
    07:19 modifié #17
    dans 1236248980:

    Pour ma part, j'utiliserais une catégorie pour ajouter la méthode convert à  NSString.

    @interface NSString (MacOSRomanToUTF8Converting)<br />- (NSString *)convert;<br />@end<br /><br />@implementation NSString (MacOSRomanToUTF8Converting)<br />- (NSString *)convert {<br />&nbsp; &nbsp; return [NSString stringWithUTF8String:[self cStringUsingEncoding:NSMacOSRomanStringEncoding]];<br />}<br />@end
    


    Puis, il suffit d'utiliser l'écriture suivante :

    NSString *chaineConvertie = [[leDico valueForKey:@&quot;nom&quot;] convert];
    



    Merci. Je ne savais la chose possible  :)
  • schlumschlum Membre
    07:19 modifié #18
    Je ne vois pas l'intérêt d'une catégorie pour ça, mais pourquoi pas.
    Mais sûrement pas avec ce nom en tout cas. La norme serait dans ce cas d'en faire un convenient constructor du genre "+stringWithString:convertedFromEncoding:toEncoding:"
  • AliGatorAliGator Membre, Modérateur
    07:19 modifié #19
    Bon j'avais pas vu qu'il y avait une 2e page, je m'apprétais à  conseiller une catégorie aussi pour le coup, ce que je trouverai pour ma part vachement plus propre (si si schlum :P). D'autant que ça permet d'utiliser la méthode depuis n'importe où ensuite dans ton code, et pas limité à  une classe dans laquelle tu écrirais la méthode convert pour l'appeler avec genre [self convert:tachaine] car si tu en as besoin dans une autre classe après bah t'es un peu bloqué.

    Par contre je suis bien d'accord, si on fait une catégorie, faut changer le nom de la méhode convert en un nom plus explicite genre -[tt](NSString*)reinterpretAsUTF8[/tt] !
  • mpergandmpergand Membre
    07:19 modifié #20
    Salut à  tous,

    Je suis en train de bidouiller sur une base sqlite3, par défaut elle gère l'utf8, mais comme elle a été faite sous windows, z'ont  mis du texte en WindowLatin1  >:(

    je procède comme ça:
    <br />char* item=result[index++];&nbsp; // resultat d&#39;une requête sql<br />NSString* str=@&quot;&quot;;<br />			<br />if(item!=NULL)<br />	{				// essai UTF8<br />	str=[NSString stringWithUTF8String:item];<br />				<br />	if(str==nil)			// essai window latin 1<br />		str=[NSString stringWithCString:item encoding: NSWindowsCP1252StringEncoding];<br />					<br />	if(str==nil)<br />		str=@&quot;&quot;;<br />	}<br /><br />
    


    Jusqu'a présent tout va bien, mais est-ce correct ?
  • schlumschlum Membre
    07:19 modifié #21
    dans 1236259302:

    Bon j'avais pas vu qu'il y avait une 2e page, je m'apprétais à  conseiller une catégorie aussi pour le coup, ce que je trouverai pour ma part vachement plus propre (si si schlum :P). D'autant que ça permet d'utiliser la méthode depuis n'importe où ensuite dans ton code, et pas limité à  une classe dans laquelle tu écrirais la méthode convert pour l'appeler avec genre [self convert:tachaine] car si tu en as besoin dans une autre classe après bah t'es un peu bloqué.

    Par contre je suis bien d'accord, si on fait une catégorie, faut changer le nom de la méhode convert en un nom plus explicite genre -[tt](NSString*)reinterpretAsUTF8[/tt] !


    Ben je ne vois toujours pas l'intérêt d'une catégorie pour ça  :P
    C'est juste une méthode qui fait de la conversion (et qui crée un nouvel objet pour ça...), et on a besoin de faire cette conversion dans une seule classe qui fait transition avec la base de donnée.
    Limite, si on se débrouille bien, on ne fait même pas de méthode, on intègre le code dans une fonction générique d'accès.

    Autant faire des catégories pour ajouter des trucs du genre "+ (NSValue*)valueWithMySpecialStruct:(MySpecialStruct)truc", ou "+ (NSString*)stringWithMyClasseQuiTue:(MyClasseQuiTue*)obj", là  je dis oui... Autant pour ce cas là , c'est un rouleau compresseur pour une mouche.
  • schlumschlum Membre
    mars 2009 modifié #22
    dans 1236269837:

    Salut à  tous,

    Je suis en train de bidouiller sur une base sqlite3, par défaut elle gère l'utf8, mais comme elle a été faite sous windows, z'ont  mis du texte en WindowLatin1  >:(

    je procède comme ça:
    ...

    Jusqu'a présent tout va bien, mais est-ce correct ?


    À mon avis, avec ce code, tu pourrais avoir des problèmes pour certains séquences...
    Par exemple, si t'as une chaà®ne Windows Latin 1 : "àƒÂ©", ton algorithme le prendra comme une chaà®ne UTF-8 "é"
    ça marche plus ou moins car en général, les chaà®nes bien françaises et pas complètement ASCII en Windows Latin 1 ne donnent pas de l'UTF-8 valide, du fait qu'un caractère non ASCII (comme les caractères accentués) est généralement suivi d'un caractère ASCII (espace, ponctuation, chiffre, minuscule de base ou majuscule de base en gros...).
    Mais je suis sûr qu'on peut trouver des contre-exemples...
  • schlumschlum Membre
    mars 2009 modifié #23
    Allez, un contre exemple qui te posera des soucis...

    "a = àŸÂ²+àŸÂ³" en Windows Latin 1 donne la chaà®ne UTF-8 valide : "a = u07F2+u07F3" (ce sont des caractères unicodes spéciaux, mais tout à  fait valides...)

    Mais j'avoue que les séquences pouvant poser des soucis sont difficiles à  générer.
    Il faut un de ces caractères : "Ààà‚àƒà„à…à†çàˆà‰àŠà‹àŒààŽààà‘à’à“à”à•à–à—à˜à™àšà›àœààžàŸ" suivi d'un de ceux là  : "€â€šÆ’„...†‡ˆ‰oe â€¹oe’‘'“”•–"˜™oe¡â€ºoe“oe¸ ¡¢£¤¥¦§¨©ª"¬®¯°Â±Â²Â³Â´ÂµÂ¶Â·Â¸Â¹Âº"¼½¾¿"
    Ou alors un de ces caractères : "à à¡âà£à¤à¥à¦çèéêëà¬à­à®à¯" suivi de deux de ceux là  : "€â€šÆ’„...†‡ˆ‰oe â€¹oe’‘'“”•–"˜™oe¡â€ºoe“oe¸ ¡¢£¤¥¦§¨©ª"¬®¯°Â±Â²Â³Â´ÂµÂ¶Â·Â¸Â¹Âº"¼½¾¿"
    Ou alors un de ces caractères : "à°à±à²à³ôàµà¶à·" suivi de trois de ceux là  : "€â€šÆ’„...†‡ˆ‰oe â€¹oe’‘'“”•–"˜™oe¡â€ºoe“oe¸ ¡¢£¤¥¦§¨©ª"¬®¯°Â±Â²Â³Â´ÂµÂ¶Â·Â¸Â¹Âº"¼½¾¿"

    Comme "TAUX_ALLOUà‰â€°" -> "TAUX_ALLOUɉ"
  • schlumschlum Membre
    mars 2009 modifié #24
    Pour de l'Espagnol, ça peut poser plus facilement souci à  cause du "¿" et du "¡" aussi... Suffit qu'ils soient précédés d'un caractère majuscule accentué et paf !

    Ah, j'avais pas vu... les "..." aussi, ça peut être méchant ! "SUPERNOVà†..." -> "SUPERNOVÆ…"
  • mpergandmpergand Membre
    07:19 modifié #25
    dans 1236296829:

    Allez, un contre exemple qui te posera des soucis...

    "a = àŸÂ²+àŸÂ³" en Windows Latin 1 donne la chaà®ne UTF-8 valide : "a = u07F2+u07F3" (ce sont des caractères unicodes spéciaux, mais tout à  fait valides...)

    Mais j'avoue que les séquences pouvant poser des soucis sont difficiles à  générer.
    Il faut un de ces caractères : "Ààà‚àƒà„à…à†çàˆà‰àŠà‹àŒààŽààà‘à’à“à”à•à–à—à˜à™àšà›àœààžàŸ" suivi d'un de ceux là  : "€â€šÆ’„...†‡ˆ‰oe â€¹oe’‘'“”•–"˜™oe¡â€ºoe“oe¸ ¡¢£¤¥¦§¨©ª"¬®¯°Â±Â²Â³Â´ÂµÂ¶Â·Â¸Â¹Âº"¼½¾¿"
    Ou alors un de ces caractères : "à à¡âà£à¤à¥à¦çèéêëà¬à­à®à¯" suivi de deux de ceux là  : "€â€šÆ’„...†‡ˆ‰oe â€¹oe’‘'“”•–"˜™oe¡â€ºoe“oe¸ ¡¢£¤¥¦§¨©ª"¬®¯°Â±Â²Â³Â´ÂµÂ¶Â·Â¸Â¹Âº"¼½¾¿"
    Ou alors un de ces caractères : "à°à±à²à³ôàµà¶à·" suivi de trois de ceux là  : "€â€šÆ’„...†‡ˆ‰oe â€¹oe’‘'“”•–"˜™oe¡â€ºoe“oe¸ ¡¢£¤¥¦§¨©ª"¬®¯°Â±Â²Â³Â´ÂµÂ¶Â·Â¸Â¹Âº"¼½¾¿"

    Comme "TAUX_ALLOUà‰â€°" -> "TAUX_ALLOUɉ"


    Tu parles l'extraterrestre couramment ?  :)

    Je pense que tout le texte de la base est en window latin, je vais faire au plus simple, je verrai bien ...

    Je me demande juste la signification exacte de:
    The default encoding for the database will be UTF-8 if sqlite3_open() is used


    Cela veut dire que les commandes sql, le nom des tables et des attributs doivent être en UTF8 ?



  • tabliertablier Membre
    07:19 modifié #26
    Je ne parle pas non plus l'extraterrestre, mais j'utilise "PopChar" qui génère à  peu près n'importe quel caractère, la preuve:
    Â¥ àž Â¼ Ò– ᾏ â“… לּ ⌘ â…œ á¹» Ô‡ Ç… ȶ â„¥ ← ↖ ↑ ⁂ ※
    :P Je n'ai aucun intérêt chez eux, mais je trouve que c'est assez pratique et je vous conseille leur programme.

    En fait, le problème principal que j'ai eu, viens des caractères diacritiques.
  • schlumschlum Membre
    07:19 modifié #27
    La " palette de caractères " génère bien plus de caractères que PopChar  ;)
  • schlumschlum Membre
    07:19 modifié #28
    dans 1236329072:

    Je me demande juste la signification exacte de:
    The default encoding for the database will be UTF-8 if sqlite3_open() is used


    Cela veut dire que les commandes sql, le nom des tables et des attributs doivent être en UTF8 ?


    C'est parce qu'il existe un "sqlite3_open16" qui travaille en UTF-16, c'est tout  ;)
    ça veut dire que quand tu bindes un type TEXT, il est interprété en UTF-8...
    http://www.sqlite.org/datatype3.html
    " TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16-LE). "
    (je suppose que BE / LE est défini par le BOM en UTF-16)
  • tabliertablier Membre
    mars 2009 modifié #29
    Juste pour le plaisir de répondre:
    La " palette de caractères " génère bien plus de caractères que PopChar 
    Absolument vrai!!  mais PopChar donne non seulement le nom des caratères, mais aussi leur valeur décimale et hexadecimale ainsi que les Tag html (à  la demande). Comme j'écris du html directement c'est assez interessant.
  • schlumschlum Membre
    07:19 modifié #30
    dans 1236342621:

    Juste pour le plaisir de répondre:
    La " palette de caractères " génère bien plus de caractères que PopChar 
    Absolument vrai!!  mais PopChar donne non seulement le nom des caratères, mais aussi leur valeur décimale et hexadecimale ainsi que les Tag html (à  la demande). Comme j'écris du html directement c'est assez interessant.


    La palète de caractères donne le nom, la valeur hexadécimale Unicode et UTF8, et tous les caractères liés (pratique quand on cherche un caractère accentué un peu spécial...).
    Plus la fonction et la catégorie dans la table unicode (noms des alphabets, tables des diacritiques etc.)

    Donc effectivement, ça ne donne pas la valeur décimale ni le tag HTML, mais je peux t'écrire en quelques minutes un utilitaire qui transforme tous les caractères non ASCII d'une NSTextView en tag HTML  :)

    Par contre, c'est gratuitement inclus dans Mac OS X  :P
  • tabliertablier Membre
    07:19 modifié #31
    Tu as raison, il manque juste la valeur décimale et les tags html dans la palette des caractères spéciaux. Et ce programme est gratuit!
    Je me suis demandé pourquoi je préfère PopChar alors qu'il est payant! Mes raisons en sont:
    1) j'utilise Pop depuis Mac OS, pratiquement depuis son origine (eh oui! l'habitude!).
    2) je trouve la présentation des fontes plus facile d'utilisation dans Pop que dans la palette.
    3) j'apprécie la simplicité d'ouverture et les réglages de fermeture automatique de sa fenêtre.
    4) Je n'ai pas trouvé, dans la palette, comment voir la fonte "Morse" que je viens d'ajouter avec le Livre des polices, alors que pop me la montre immédiatement.

    Dans la palette, je retiens la présentation par 'famille de caractère' qui doit permettre de trouver rapidement certains caractères peu courant.

    Quand à  écrire une transcription texte -> tag, Le premier jet en 5 mn, OUI: &#xxxx; et basta!
    Si tu veux utiliser les tags du genre: &Ntilde; &ordf; &Ugrave; &sect;... etc. Il faut te référer à  des tables qu'il faut construire, c'est déjà  plus long. Puis tu découvres que certains Browsers maltraitent les caractères diacritics et qu'il vaut mieux les transcrire! Enfin de compte, tu es content si tu termines dans la journée!  J'ai mis plus de 48h, mais je ne suis pas informaticien!!

Connectez-vous ou Inscrivez-vous pour répondre.