Visual C++ MFC Unicode

Hallo, mein erster Beitrag:

Um Postgres zu erlernen, habe ich direkt einen MFC Dialog erstellt. Damit gehe ich die verschiedenen Funktionen der libpqxx durch. Das Projekt ist als _UNICODE aufgesetzt, die Datenbank hat UTF8 Encoding und WIN1052 Sortierung.
Beim Insert von Beispieldaten:

	/* Create SQL statement */
			string sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
				"VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
				"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
				"VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
				"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
				"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
				"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
				"VALUES (4, 'Jörg', 25, 'Rich-Mond ', 65000.00 );";

bekomme ich beim Umlaut in ‘Jörg’ eine Fehlermeldung:

FEHLER: ungültige Byte-Sequenz für Kodierung „UTF8“: 0xf6 0x72 0x67 0x27

Das passiert sowohl beim Insert aus dem Quelltext heraus, als auch bei einer Tippeingabe in einem CEdit Control.

Weiß jemand Rat?

Gruß, Metzi

ich tippe auf falsches client_encoding.

Hallo, das war das letzte was ich noch probiert hatte. Vor dem Insert steht:

string enc = "utf8";
C.connection_base::set_client_encoding(enc);

Half leider nicht.

test=# show client_encoding;
client_encoding

UTF8
(1 row)

keine Ahnung, ob das case-sensitive ist …

Das show_client_endcoding war schon mal gut. Ich hab es im Source gesendet und das CRichEditControl (für alle Ausgaben) gibt richtigerweise UFT8 aus.

In meinem Unicode-Programm flogen mir zum ersten Male die ganzen String-Konversionen um die Ohren. libpqxx erwartet durchweg string, leider nicht wstring. Ein SQL-Insert, einer string-Variablen zugewiesen, gab aber eben obige Fehlermeldung wegen des Umlauts. Nach Hin- und Her bei Internet-Recherche, geht es nun also so:

SQL-Befehl einem wide char zuweisen, d. i. ein 16-bit Unicode:

wchar_t *sql = L"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Jörg', 32, 'California', 20000.00 ); ";

Mit dieser gefundenen Funktion den wide char umwandeln in einen libpqxx angenehmen string:

string toNarrowString(const wchar_t* pStr, int len)
{
	ASSERT(len >= 0 || len == -1);

	// figure out how many narrow characters we are going to get
	int nChars = WideCharToMultiByte(CP_UTF8, 0, pStr, len, NULL, 0, NULL, NULL);
	if (len == -1)
		--nChars;
	if (nChars == 0)
		return "";
	string buf;
	buf.resize(nChars);
	WideCharToMultiByte(CP_UTF8, 0, pStr, len, const_cast<char*>(buf.c_str()), nChars, NULL, NULL);

	return buf;
}

Der Aufruf geht dann so:

W.exec( toNarrowString(sql,-1  ) );

Was Unicode 8bit (UTF8) dann Besonderes hat, bleibt mir ein Rätsel. Aber o.k. Hierfür geht es ja nun.