[C++] Webseite abfragen - Codierung
-
Hi,
ich schreibe ein Programm, mit dem ich eine Webseite (eine PHP-API) abfragen möchte.
Die Rückgabe des PHP-Scripts ist z.B.<?php // KAS Schnittstelle $kas_schnittstelle_version = "2010-11-03"; $kas_flood_delay = "2"; $returnstring = "kas_password_incorrect"; $returninfo = ""; ?>Mich interessiert jetzt die Zeile mit dem $returnstring. Dazu zerlege ich die Rückgabe in Zeilen (das funktioniert) und lasse über jede Zeile ein wxRegEx drüberlaufen.
DWORD bytesRead; char Return[1024]; std::string data; HINTERNET hOpen = InternetOpen("Internet Explorer",INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, NULL); HINTERNET hFile = InternetOpenUrl(hOpen,url.c_str(), NULL, NULL, INTERNET_FLAG_RELOAD, NULL); bool success = true; while ((success = InternetReadFile(hFile, Return, sizeof(Return), &bytesRead)) && bytesRead != 0) { data.append(Return, bytesRead); } if (success == false) { InternetCloseHandle(hOpen); InternetCloseHandle(hFile); return std::string("no_api"); } else { //Alle Zeilen durchgehn... wxRegEx ttx = wxT("^\\$returnstring = \"([a-zA-Z0-9_]+)\";$"); std::vector<std::string> Lines = SplitString(data,"\n",false); for(std::vector<std::string>::iterator it=Lines.begin();it!=Lines.end();it++) { if (ttx.Matches(it->c_str())) { wxString text = ttx.GetMatch(it->c_str(), 1); InternetCloseHandle(hOpen); InternetCloseHandle(hFile); return text.c_str(); } } } InternetCloseHandle(hOpen); InternetCloseHandle(hFile); return "FALSE";Das Problem ist, dass nie in den if-Zweig von if (ttx.Matches(it->c_str())) gegangen wird, die Methode liefert immer FALSE zurück
Meine Vermutung ist, dass irgendwas mit der Zeichen-Codierung nicht stimmt. Das Programm ist auf Multi-Byte eingestellt, das PHP-Script sollte UTF8 sein.
Kann mir jemand weiterhelfen?
Gruß
-
Was sagt denn der Debugger, was in dem vector drinsteht? Ist alles da?
Hat der String vielleicht Leerzeichen vorne oder hinten, dann würde die Regex nicht greifen. Wenn der richtige String drinsteckt, dann debug doch mal ins Matches(), um zu schauen, warums nicht hinhaut.
-
Hi,
Der Vector ist in Ordnung, sind auch keine zusätzlichen Leerzeichen etc. drin.
Das Zerlegen in einzelne Zeilen funktioniert auch.
Das Komische ist, der Quellcode hatte schonmal funktioniert. Seit dem ich das Projekt jedoch auf Unicode- und wieder zurück auf Multi-Byte umgestellt hatte, funktioniert es nichtmehr.
Deshalb meine Vermutung, dass etwas an der Codierung nicht stimmt.Gruß
-
Hi,
Seltsame Sache.
Ich hab den Code jetzt auf std::tr1::regex umgestellt, und da funktioniert es mit den gleichen Ausgangs-Daten...Gruß
-
Ich hab ein neues Problem:
Die Rückgabe des PHP-Scripts kann auch Umlaute enthalten.
Wie kann ich in C++ aus dem UTF-8-String des PHP-Scripts einen Multi-Byte String machen, damit die Umlaute richtig angezeigt werden?
-
Hi,
hat niemand ne Idee?
Ich hab versucht das Programm auf Unicode umzustellen, allerdings bekomme ich bei folgendem Code eine Fehlermeldung:std::tr1::wregex rx(L"^\\$returnstring = \"([a-zA-Z0-9_]+)\";$"); std::vector<std::wstring> Lines = SplitString(data,L"\n",false); for(std::vector<std::wstring>::iterator it=Lines.begin();it!=Lines.end();it++) { if (std::tr1::regex_match(it->begin(),it->end(),rx)) { std::tr1::wsmatch res; std::tr1::regex_search(std::wstring(it->c_str()),res,rx); InternetCloseHandle(hOpen); InternetCloseHandle(hFile); return std::wstring(res[1]); } }Die Fehlermeldung kommt in der return-Zeile (hab ich durch Breakpoints rausbekommen):
Debug Assertion Failed!
Programm: [...]
File: [...]
Line: [...]Expression: string iterators incompatible
[...]Weis jemand woran das liegen kann?
Gruß
-
Raven280438 schrieb:
Seltsame Sache.
Ich hab den Code jetzt auf std::tr1::regex umgestellt, und da funktioniert es mit den gleichen Ausgangs-Daten...Dann ist vielleicht dein wx-Regex Ausdruck falsch, wenn die Regex die Korrekte Zeile nicht matched?
Raven280438 schrieb:
Die Fehlermeldung kommt in der return-Zeile (hab ich durch Breakpoints rausbekommen):
Weis jemand woran das liegen kann?[/quote]
Ich rate mal: du greifst einfach so auf res[1] zu. res ist im Grunde ein Container, genauer ein std::vector. Du hast vorher nirgendwo abgefragt, wieviele matches es denn gegeben hat. res[1] wäre der zweite match, der erste liegt ziemlich sicher in res[0]. Banaler Zugriffsfehler also.
-
Hi,
danke für die Antwort.
res[0] sollte doch eingedlich der gesamte String sein, res[1] der erste Match (ist zumindest bei allen Regexs die ich kenne (PHP, C#) so.
Ich habs trotzdem mal mit res[0] probiert und bekomme den gleichen Fehler.
Gruß
-
Dann setz dir mal bitte einen Brechpunkt vor die return-Anweisung und schau, was in res überhaupt drin ist.
-
pumuckl schrieb:
Brechpunkt

-
Hi,
da stehn nur seltsame Zeichen drin. Muss wohl irgendwas an der Codierung falsch sein denk ich mal...
-
Warum übergibst du eigentlich String-iteratoren an regex_match und nicht einfach die Strings? Und warum einen c_str an regex_search?
-
Hi,
ich hatte mir ein Beispiel angesehn, wo das so gemacht wurde, deshalb hab ichs übernommen

Ändert aber auch nichts an den Fehlern...
-
Dann reduzier dein Problem mal bitte auf ein minimales compilierbares Beispiel, mit dem wir es nachvollziehen können, d.h. im Einzelnen:
- lass den internetkram weg
- befüll den vector stattdessen "zu fuß", d.h. einfach festkodiert deine 2-3 Strings reinbastelnSollte alles zusammen in 20-30 Zeilen machbar sein. Wenns compiliert und bei dir immernoch den Fehler bringt, her damit, dann können wir dir helfen

-
Hi,
vielleicht liegt aber grad in diesem Internet-Kram die Lösung meines Problems

Ich hab mittlerweile 2 Versionen des Programms, eine mit Multi-Byte-Zeichensatz und eine in Unicode-Zeichensatz.
Die Multi-Byte-Version läuft, allerdings werden da Umlaute falsch angezeigt.
Die Unicode-Verion läuft nicht, da gibt es die hier beschriebenen Fehler.Vielleicht ist es Ziel-führender, wenn ich mich nochmal über die Multi-Byte-Version hermache.
Ich habe halt nirgends etwas gefunden, wie man eine PHP-API (eine normale Webseite mit PHP-Code als Quellcode), die in UTF8 codiert ist, in ein Multi-Byte Programm einliest, ohne dass Umlaute kaputt gehn.
Ich benutze dazu InternetOpen, InternetOpenUrl und InternetReadFile, hab aber nirgends was gefunden, wie man die Codierung der Webseite einstellt.Vielleicht kann mir ja hier jemand weiterhelfen?
Gruß
-
Raven280438 schrieb:
vielleicht liegt aber grad in diesem Internet-Kram die Lösung meines Problems

Kann durchaus sein. Wenn du den Internetkram entfernst und alles andere lässt, und wenn dadurch das Problem verschwindet, weißt du schon mehr. Nur müssen wir dann nicht in den Regexen nach Fehlern suchen

Lass es uns wissen, wenns nicht mehr ein C++-Problem sondern was anderes ist. Du wirst dann ins passende Forum verschoben.
-
Raven280438 schrieb:
Ich habe halt nirgends etwas gefunden, wie man eine PHP-API (eine normale Webseite mit PHP-Code als Quellcode), die in UTF8 codiert ist, in ein Multi-Byte Programm einliest, ohne dass Umlaute kaputt gehn.
Du bekommst die Daten in UTF-8 und willst sie in ein Format umwandeln, mit dem du gut arbeiten kannst. Da bieten sich ISO-8859-1 oder natürlich UCS-2 bzw UCS-4 an.
Zur Umwandlung nimm irgendeine passende Library, z.B. die dicke ICU. boost könnte mit den passenden Locales, Facets oder was weiß ich auch gehen.
-
Hi,
hat schonmal jemand mit ICU gearbeitet und kann mir auf die Sprünge helfen?
Ich arbeite grad die Documentation durch, aber so richtig blick ich nich durch...Gruß