2009-11-19 4 views
0

J'essaie de savoir si deux chaînes que j'ai sont les mêmes, à des fins de tests unitaires. Le premier est une chaîne prédéfinie, codée en dur dans le programme. La seconde est une lecture à partir d'un fichier texte avec un ifstream utilisant std :: getline(), puis prise comme une sous-chaîne. Les deux valeurs sont stockées en tant que chaînes C++.C++ - string.compare les problèmes lorsque la sortie vers un fichier texte est différente de la sortie de la console?

Quand je sortie les deux cordes à la console à l'aide pour les tests Cout, ils ont tous deux semblent identiques:

ThisIsATestStringOutputtedToAFile ThisIsATestStringOutputtedToAFile

Cependant, les déclarations de String.Compare indiquant qu'ils ne sont pas égaux. Lors de la sortie dans un fichier texte, les deux chaînes apparaissent comme suit:

ThisIsATestStringOutputtedToAFile T^@ h^@ i^@ s^@ I^@ s^@ A^@ T^@ e^@ s^@ t^@ S^@ t^@ r^@ i^@ n^@ g^@ O^@ u^@ t^@ p^@ u^@ t^@ t^@ e^@ D^@ T^@ o^@ A^@ F^@ i^@ l^@ e

Je suppose que c'est une sorte de problème d'encodage, et si j'étais dans ma langue maternelle (bon vieux C#), je wouldn pas trop de problèmes. Comme je suis avec C/C++ et Vi, et franchement ne sais pas vraiment où aller à partir d'ici! J'ai essayé de convertir peut-être/de ansi/unicode, et aussi en supprimant les caractères étranges, mais je ne suis même pas sûr si elles existent vraiment ou pas ..

Merci d'avance pour toute suggestion.

EDIT Toutes mes excuses, c'est la première fois de poster ici. Le code ci-dessous est comment je vais passer par le processus:

ifstream myInput; 
ofstream myOutput; 

myInput.open(fileLocation.c_str()); 
myOutput.open("test.txt"); 

TEST_ASSERT(myInput.is_open() == 1); 

string compare1 = "ThisIsATestStringOutputtedToAFile"; 
string fileBuffer; 

std::getline(myInput, fileBuffer); 
string compare2 = fileBuffer.substr(400,100); 

cout << compare1 + "\n"; 
cout << compare2 + "\n"; 
myOutput << compare1 + "\n"; 
myOutput << compare2 + "\n"; 
cin.get(); 

myInput.close(); 
myOutput.close(); 

TEST_ASSERT(compare1.compare(compare2) == 0); 
+0

On dirait que votre deuxième chaîne est 2byte unicode? – falstro

+1

Vous devez nous indiquer les types exacts des chaînes, comment vous les produisez, et comment vous les comparez - dans le code s'il vous plaît. – sbi

Répondre

0

Il se trouve que le problème est que le codage de fichier de myInput était UTF-16, alors que la chaîne de comparaison était UTF-8. La façon de les convertir avec les limitations d'OS que j'avais pour ce projet (Linux, le code C/C++), était d'utiliser les fonctions iconv(). Pour conserver la compatibilité des chaînes C++ j'été utilisé, je fini par sauver la chaîne dans un nouveau fichier texte, en cours d'exécution puis iconv par la commande système().La lecture de la chaîne sortie en retour m'a ensuite donné la chaîne dans le format dont j'avais besoin pour que la comparaison fonctionne correctement. Je suis conscient que ce n'est pas le moyen le plus efficace de le faire. J'ai eu le luxe d'un environnement Windows et les bibliothèques windows.h, les choses auraient été beaucoup plus faciles. Cependant, dans ce cas, le code faisait partie de tests unitaires rarement utilisés et n'avait donc pas besoin d'être hautement optimisé, d'où la création, la destruction et les opérations d'E/S de certains fichiers texte.

0

Les œuvres suivantes pour moi et écrit le texte collé ci-dessous dans le fichier. Notez le caractère '\0' incorporé dans la chaîne.

#include <iostream> 
#include <fstream> 
#include <sstream> 

int main() 
{ 
    std::istringstream myInput("ThisIsATestStringOutputtedToAFile\x0 12ou 9 21 3r8f8 reohb jfbhv jshdbv coerbgf vibdfjchbv jdfhbv jdfhbvg jhbdfejh vbfjdsb vjdfvb jfvfdhjs jfhbsd jkefhsv gjhvbdfsjh jdsfhb vjhdfbs vjhdsfg kbhjsadlj bckslASB VBAK VKLFB VLHBFDSL VHBDFSLHVGFDJSHBVG LFS1BDV LH1BJDFLV HBDSH VBLDFSHB VGLDFKHB KAPBLKFBSV LFHBV YBlkjb dflkvb sfvbsljbv sldb fvlfs1hbd vljkh1ykcvb skdfbv nkldsbf vsgdb lkjhbsgd lkdcfb vlkbsdc xlkvbxkclbklxcbv"); 
    std::ofstream myOutput("test.txt"); 
    //std::ostringstream myOutput; 

    std::string str1 = "ThisIsATestStringOutputtedToAFile"; 
    std::string fileBuffer; 

    std::getline(myInput, fileBuffer); 
    std::string str2 = fileBuffer.substr(10,100); 

    std::cout << str1 + "\n"; 
    std::cout << str2 + "\n"; 
    myOutput << str1 + "\n"; 
    myOutput << str2 + "\n"; 

    std::cout << str1.compare(str2) << '\n'; 

    //std::cout << myOutput.str() << '\n'; 
    return 0; 
} 

Sortie:

 
ThisIsATestStringOutputtedToAFile 
ThisIsATestStringOutputtedToAFile 
1

Comment avez-vous créé le contenu de myInput? Je suppose que ce fichier est créé en codage à deux octets. Vous pouvez utiliser hex-dump pour vérifier cette théorie ou utiliser un éditeur différent pour créer ce fichier.

La manière simpliest serait de lancer cmd.exe et tapez

echo "ThisIsATestStringOutputtedToAFile" > test.txt

MISE À JOUR:

Si vous ne pouvez pas modifier le codage du fichier myInput, vous pouvez essayer d'utiliser Larges caractères dans votre programme. C'est à dire. utiliser wstring au lieu de string, wifstream au lieu de ifstream, wofstream, wcout, etc.

+0

Le contenu de myInput est un fichier XML d'extension de fichier personnalisé, bien que leur ouverture avec vi le montre comme étant un fichier binaire. Lire et imprimer le fichier ligne par ligne à la console l'affiche bien, donc je devine que je dois le convertir d'un flux binaire à un flux de type ACSII? – Smallgods

+0

Lorsque vous imprimez le fichier sur la console, les caractères dont le code ASCII est inférieur à 32 sont traités comme des codes de contrôle (par exemple, TAB, CR, LF, etc.). Le caractère^@ (ASCII 0x00) ne fait rien, il est simplement ignoré. Vi reconnaît le fichier comme binaire à cause de ces caractères^@. –

+0

Le fichier myInput était au format binaire, semble-t-il. Quelques recherches plus poussées ont conduit à cet article qui m'a bien mis sur mon chemin. Salutations pour l'aide! http://stackoverflow.com/questions/181634/simplest-efficient-ways-to-read-binary-and-ascii-files-to-string-or-similar-in-v – Smallgods

Questions connexes