Unten, ich produziere sowohl gebrochenen Code und eine feste Version der gleichen. Das Problem ist, dass ich mir nicht vollständig erklären kann, warum das erstere nicht funktioniert, aber das letztere. Ich muss natürlich ein sehr grundlegendes Konzept der C++ - Sprache überprüfen: Könnten Sie Hinweise geben, was ich überprüfen sollte, und möglicherweise auch eine Erklärung geben, warum ich die Ergebnisse bekomme, die ich mit dem kaputten Code erhalte?Grundlegende Konzepte mit Std :: String Referenzen, Std :: Regex und Boost :: Dateisystem
In dem Verzeichnis "../docs/", auf das im Code verwiesen wird, habe ich einfach den "touch" -Befehl unter Linux verwendet, um eine Anzahl doc ...... html-Dateien verschiedener Länge zu erstellen.
#include <iostream>
#include <regex>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
int main() {
fs::path p("../docs/");
for (auto& dir_it : fs::directory_iterator(p)) {
std::regex re = std::regex("^(doc[a-z]+)\\.html$");
std::smatch matches;
// BROKEN HERE:
if (std::regex_match(dir_it.path().filename().string(), matches, re)) {
std::cout << "\t\t" <<dir_it.path().filename().string();
std::cout << "\t\t\t" << matches[1] << std::endl;
}
}
return 0;
}
Produziert:
documentati.html ati
documentationt.html �}:ationt
document.html document
documenta.html documenta
docume.html docume
documentat.html documentat
docum.html docum
documentatio.html ��:atio
documen.html documen
docu.html docu
documentation.html ��:ation
documaeuaoeu.html ��:aoeu
Anmerkung 1: Die obige Fehler bei Dateinamen ausgelöst wird, die über eine bestimmte Länge sind. Ich verstehe nur, weil das std :: string-Objekt die Größe selbst ändert.
Anmerkung 2: Der obige Code ist sehr ähnlich als der Code in der folgenden Frage verwendet, aber mit boost :: regex_match statt std :: regex_match: Can I use a mask to iterate files in a directory with Boost?
Es wird verwendet für mich vor als gut zu funktionieren, aber jetzt benutze ich GCC 5.4 anstelle von GCC 4.6, std :: regex anstelle von boost :: regex, C++ 11 und eine viel neuere Version von boost :: filesystem. Welche Änderung ist relevant, was dazu geführt hat, dass Arbeitscode kaputt gegangen ist?
Korrigiert:
#include <iostream>
#include <regex>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
int main() {
fs::path p("../docs/");
for (auto& dir_it : fs::directory_iterator(p)) {
std::regex re = std::regex("^(doc[a-z]+)\\.html$");
std::smatch matches;
std::string p = dir_it.path().filename().string();
if (std::regex_match(p, matches, re)) {
std::cout << "\t\t" <<dir_it.path().filename().string();
std::cout << "\t\t\t" << matches[1] << std::endl;
}
}
return 0;
}
produziert:
documentati.html documentati
documentationt.html documentationt
document.html document
documenta.html documenta
docume.html docume
documentat.html documentat
docum.html docum
documentatio.html documentatio
documen.html documen
docu.html docu
documentation.html documentation
documaeuaoeu.html documaeuaoeu
mit boost 1.62.0-r1 und gcc (Gentoo 5.4.0-r3), die boost :: filesystem Dokumentation erscheint nicht auf bietet einen klaren Hinweis darauf, welchen Weg() Dateiname() string() liefert:.. http://www.boost.org/doc/libs/1_62_0/libs/filesystem/doc/reference.html#path-filename
es scheint, dass es abhängt:
Why does boost::filesystem::path::string() return by value on Windows and by reference on POSIX?
Oh! Jetzt, wo ich es sehe, scheint es offensichtlich. +1. Vielen Dank für Ihre Zeit. – augustin