Avatar billede kjeldsted Novice
30. januar 2012 - 22:55 Der er 13 kommentarer og
1 løsning

Regex sætning i C++

Hejsa alle eksperter.

Jeg er stødt ind i et lille problem i et C++ program som jeg håber der er nogle der kan hjælpe mig med.
Først og fremmest vil jeg lige sige at jeg ikke er voldsomt meget inde i C++da jeg ikke har programmeret ret meget hér og derfor kun kender til det mest basale. Jeg kommer fra en baggrund som PHP programmør.
Men problemet er som følger.

Jeg har en logfil hvori jeg skal have hevet nogle informationer ud. Et eksempel på nogle linjer i denne fil kunne fx. være
Jan 30 16:16:17 jenskjeldsted proftpd[14105] jenskjeldsted (::ffff:202.164.46.163[::ffff:202.164.46.163]): USER anonymous: no such user found from ::ffff:202.164.46.163 [::ffff:202.164.46.163] to ::ffff:192.168.1.6:21
Jan 30 16:16:17 jenskjeldsted proftpd[14105] jenskjeldsted (::ffff:202.164.46.163[::ffff:202.164.46.163]): FTP session closed.
Jan 30 16:16:17 jenskjeldsted proftpd[14108] jenskjeldsted (::ffff:202.164.46.163[::ffff:202.164.46.163]): FTP session opened.
Jan 30 16:16:27 jenskjeldsted proftpd[14108] jenskjeldsted (::ffff:202.164.46.163[::ffff:202.164.46.163]): USER administrator: no such user found from ::ffff:202.164.46.163 [::ffff:202.164.46.163] to ::ffff:192.168.1.6:21
Jan 30 16:16:29 jenskjeldsted proftpd[14108] jenskjeldsted (::ffff:202.164.46.163[::ffff:202.164.46.163]): FTP session closed.
Jan 30 16:18:23 jenskjeldsted proftpd[14887] jenskjeldsted (::ffff:202.164.46.163[::ffff:202.164.46.163]): FTP session opened.


I denne fil er jeg så interesseret i at finde IP'en i de liner der er logget som
USER administrator: no such user found from ::ffff:202.164.46.163


Selvfølgelig kan "administrator" samt selve IP'en variere (egentlig selvsagt), og kan jo regne ud at jeg skal have fat i noget Regular expressions til at finde frem til 202.164.46.163.
Jeg burde være i stand til at skrive selve mønsteret der skal kigges efter, men vejen hértil og hvordan og hvorledes jeg er ret usikker på.

Jeg kan forstå at der som standard ikke er et regex bibliotek i C++, så først og fremmest skal jeg have fundet et hertil.

Jeg håber der er en der kan hjælpe med dette og gerne holde mig lidt i hånden, da jeg ikke er så godt inde i tingene omkring computer programmering endnu.

Jeg kan som bonus oplyse det er et Unix program, programmeret på Linux (Ubuntu) med G++ compileren.

På forhånd tak :)
Avatar billede kjeldsted Novice
30. januar 2012 - 22:56 #1
Og lad mig lige for en god ordens skyld nævne at alle linjerne i eksemplet her over begynder med "Jan", men Eksperten bryder jo linjerne op.
Avatar billede arne_v Ekspert
30. januar 2012 - 23:18 #2
Hvis du kender PHP hvorfor lavr du det saa ikke i PHP?

(man kan godt lave command line scripts i PHP)
Avatar billede kjeldsted Novice
30. januar 2012 - 23:25 #3
Tja. Det kan der jo egentlig være noget om.

Altså jeg skal lærer det andet før eller siden... Men har faktisk slet ikke slået mig at jeg ville kunne gøre det med et lokalt PHP.
Avatar billede arne_v Ekspert
30. januar 2012 - 23:36 #4
foobar.php

<?php
echo "Det virker!";
?>

og:

php foobar.php

burde virke (muligvis skal du lige hav full path til php programmet)
Avatar billede arne_v Ekspert
30. januar 2012 - 23:36 #5
Men jeg kan godt lave en C++ loesning.
Avatar billede kjeldsted Novice
30. januar 2012 - 23:51 #6
Nu har jeg prøvet med følgende:

test.cpp
#include <iostream>

int main() {
  php /www/ext_hosts/kjeldsted.net/test.php;
}

test.php
<?
echo "Hello World!";
?>

Compileren retunere
test.cpp:4: error: 'php' was not declared in this scope
Avatar billede arne_v Ekspert
31. januar 2012 - 00:48 #7
php /www/ext_hosts/kjeldsted.net/test.php

skal koeres paa kommando prompten - det har slet ikke noget med C++ at goere.
Avatar billede arne_v Ekspert
31. januar 2012 - 00:49 #8
Hvis jeg skal bixe et C++ eksempel, hvilket regex lib har du saa installeret?
Avatar billede kjeldsted Novice
31. januar 2012 - 14:04 #9
Ah, ja. Selvfølgelig... Jeg ville nok foretrække at holde det i C++.

Og jeg har netop fået installeret Boost og har også fået en match til at fungere. Men du må da gerne bixe noget sammen, hvis du kan/gider :)
Avatar billede kjeldsted Novice
01. februar 2012 - 01:06 #10
Okay. Har fået bikset noget sammen nu. Men undre mig lidt over en lille ting. Jeg har ingen problemer med at compile koden. Men der kommer en fejl i runtime
Jan 30 01:58:50 jenskjeldsted proftpd[22996] jenskjeldsted (::ffff:86.48.54.30[::ffff:86.48.54.30]): FTP session opened.
terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_S_construct NULL not valid
Aborted


Så vidt jeg kan se når vi hele vejen ned til if(regex_match(response, what, expression)) { inden at denne fejl optræder. Udkommentere jeg const char* response = sLine.c_str(); og fx i stedet skriver const char* response = "En tekst som den skal tjekke" der er ingen problemer med hverkena at køre programmet, eller for den sags skyld at fortælle om der er match eller ej. Men hvorfor får jeg denne fejl?

.cpp koden:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <boost/regex.hpp> 

using namespace boost;
using namespace std;

regex expression(".*(no\\ such\\ user\\ found\\ from).*:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}).*");

string wrongUser(string sLine) {
    cmatch what;
    const char* response = sLine.c_str();
    cout << response << endl;
    if(regex_match(response, what, expression)) {
        /*cout << "0: " << what[0] << endl;
        cout << "1: " << what[1] << endl;
        cout << "2: " << what[2] << endl;
        cout << "3: " << what[3] << endl;*/
        return what[2];
    }
    else return 0;
}

int main() {
    vector<string> v;
    string sLine;
    ifstream gadminLog ("/var/log/secure");
    if(gadminLog.is_open()) {
        int iU = 0;
        while(gadminLog.good()) {
            getline (gadminLog,sLine);
            //cout << line << endl;
            v.push_back(sLine);
            iU++;
        }
        gadminLog.close();
    }
    else cout << "Filen kunne ikke åbnes";
   
    //cout << "Hello world!" << endl;

    for(int i=0; i < v.size();i++) {
        string sBuff;
        string sIPBuff;
        if(!v[i].empty()) {
            sBuff = v[i].substr(7,8);
            cout << wrongUser(v[i]) << endl;
            //cout << sBuff << "\t" << v[i] << endl;
            //cout << v[i] << endl;
        }
    }
    cout << "Done!" <<endl;
    return 0;
}


Ps. Ja, noget af det er lidt rodet. Men ville lige have styr på et par ting inden jeg ren-skrev koden.
Avatar billede arne_v Ekspert
02. februar 2012 - 03:17 #11
Jeg undrer mig over at du ikke checker paa returvaerdi fra getline.
Avatar billede arne_v Ekspert
02. februar 2012 - 03:25 #12
Jeg tror at du faar laest en ikke eksisterende linie ind til sidst.
Avatar billede kjeldsted Novice
02. februar 2012 - 12:12 #13
Det undre mig i så fald bare at den runtime error kommer første gang at wrongUser() bliver kaldt. Så vidt jeg kan se hvis jeg udskriver under indlæsning af fil (linjen: //cout << sBuff << "\t" << v[i] << endl;) så er det ikke som sådan noget galt nogle steder. Jeg kan godt se du har ret i at jeg glemmer at tjekke om der er en returværdi på getline. Men så brude jeg vel i runtime stadig kunne udskrive indtil jeg når sidste linje?

Har desuden fundet følgende tekst fra Boost:
There is an existing bug though that means that accessing the regex as a
string doesn't work (will be fixed in the next release).

http://web.archiveorange.com/archive/v/Q0J4V3wj7MA84XWjZ4f1

Version 1.48 af Boost, som er den jeg benytter.
Avatar billede kjeldsted Novice
28. marts 2012 - 21:03 #14
Har vist mere eller mindre droppet programmet. I hvert fad for nu
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester