[C] Probleempje met sscanf

Pagina: 1
Acties:

  • -W0kk3L-
  • Registratie: Juni 2002
  • Laatst online: 20-12-2025
Wie kan mijn verder helpen met het volgende probleem.
Ik heb de volgende regel als invoer:
code:
1
log L 08/25/2005 - 16:24:32: "[CLAN]NAAMPJE[CL]<265><STEAM_0:1:23456789><>" STEAM USERID validated

Met de volgende code haal ik daar zonder problemen de NICK en UID uit:
code:
1
sscanf(str2, "%[^\"]\"%[^<]<%[^<]<%[^>]>%[^\n]", NULLSTR, NICK, NULLSTR, UID, NULLSTR);

Ik krijg dan keurig als NICK "[CLAN]NAAMPJE[CL]" en UID "STEAM_0:1:23456789".

Het probleem begint echt als ik bijvoorbeeld de volgende invoerstring krijg.
code:
1
log L 08/25/2005 - 16:24:32: "[CLAN]<NAAMPJE>[CL]<265><STEAM_0:1:23456789><>" STEAM USERID validated

In deze logregel zitten ook de tekens die ik gebruik voor de delimiter (namelijk, de < en de >). Met als gevolg dat de variabelen er niet goed uitkomen (de naam wordt half afgebroken, en het UID komt er helemaal niet uit. Bovendien gaat de volgende regel ook fout.) Heeft iemand een suggestie hoe ik dit op kan lossen? Het getal na de naam (dus in dit geval 265) is wisselen en kan bijv ook 1 karakter zijn), maar deze heb ik verder niet nodig. De rest is statisch met uitzondering van de datum en tijd uiteraard.

Iemand een suggestie?

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Tsja, ik zou een andere delimeter hebben gekozen, maar daar heb je nu niks meer aan. :P

Misschien is het een idee om een eigen functie te maken die de string van achteren naar voren leest? Dan is sowieso de tweede keer dat je een > tegenkomt alle tekst daarvoor tot aan de volgende < het UID. Vervolgens krijg je dat nummer, dat kun je dan weer overslaan. Daarna is het gewoon een kwestie van alles vanaf de 31e positie (index 30 in je array/string dus) tot aan de positie waar je gestopt bent met het achteruit lezen op te vatten als naam. Lijkt me niet al te moeilijk. :)

Ik denk in elk geval niet dat het je met sscanf gaat lukken.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • -W0kk3L-
  • Registratie: Juni 2002
  • Laatst online: 20-12-2025
De delimiter kiezen kan ik helaas niet doen. Zo wordt hij aangeleverd (door CS, de betreffende game).

Je oplossing is idd een aardig. Ik ga er wel even mee puzzelen. Mocht iemand nog meer goeie oplossingen weten, graag! :)

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Als er elke keer [CLAN] en [CL] omheen zit, dan kan je het zo doen:
code:
1
sscanf(str2, "%*[^\"]\"[CLAN]%[^[][CL]<%*[^<]<%[^>]>%*[^\n]", nick, uid);



offtopic:
Had ik net niet een reply met onzin?

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Niet iedereen speelt met dezelfde clan-naam en -afkorting lijkt me. :P

offtopic:
Ik heb geen onzinreply gezien. :P

offtopic:
[.oisyn] ik wel, heb 'm verwijderd ;)

[ Voor 19% gewijzigd door .oisyn op 26-08-2005 14:47 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

kijk eens naar de regexpen die psychostats gebruikt. die staan ergens in een apart filetje bij de source.
ik zou dan ook sscanf niet gebruiken want die doet rare dingen als ie niet tegenkomt wat ie wil tegenkomen voor zover ik weet. bovendien weet'k niet wat het doel is, maar met regexp'en kom je denk'k een stuk verder en scripttalen zoals AWK zijn daar super in ;)


off-topic:
zo, ik kom de Wokkel van nexus hier nog eens tegen ;) remember me? de oude RL-kneus?
Aangezien jullie nog hosten kan ik jullie dit linkje wel eens aanbevelen ;)

[ Voor 83% gewijzigd door H!GHGuY op 26-08-2005 14:33 ]

ASSUME makes an ASS out of U and ME


  • -W0kk3L-
  • Registratie: Juni 2002
  • Laatst online: 20-12-2025

off-topic:
Hehe, ja hoor, ik herinner mij nog wel. Woonde jij trouwens ook niet in dezelfde plaats? :)


Nee, de namen zijn uiteraard niet allemaal van hetzelfde type (met clan etc), was het maar zo makkelijk :)

  • Daos
  • Registratie: Oktober 2004
  • Niet online
-NMe- schreef op vrijdag 26 augustus 2005 @ 14:26:
Niet iedereen speelt met dezelfde clan-naam en -afkorting lijkt me. :P
Als er elke keer [..] bij het begin en eind staat en er verder geen [ in voor mag komen dan wordt het:
code:
1
2
3
4
sscanf(str2, "%*[^\"]\"[%[^]]]%[^[][%[^]]]<%*[^<]<%[^>]", clan, nick, cl, uid);

printf("NICK =  [%s]%s[%s]\n", clan, nick, cl);
printf("UID  =  %s\n", uid);


Is er ook ergens een specificatie die beschijft hoe die nickname eruit ziet?

[edit]
Als ik even op google kijk, dan lijkt het erop dat echt alles mag.
Iets anders dan [rml]-NMe- in "[ C] Probleempje met sscanf"[/rml] kan ik ook niet bedenken.

[ Voor 37% gewijzigd door Daos op 26-08-2005 15:28 ]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

-W0kk3L- schreef op vrijdag 26 augustus 2005 @ 14:42:

off-topic:
Hehe, ja hoor, ik herinner mij nog wel. Woonde jij trouwens ook niet in dezelfde plaats? :)

off-topic:
* H!GHGuY = op en top Belg uit Brugge

ASSUME makes an ASS out of U and ME


  • -W0kk3L-
  • Registratie: Juni 2002
  • Laatst online: 20-12-2025
het ging niet ideaal met sscanf.... dus toch naar een andere manier gezocht. En met een beetje hulp is het gelukt.

code:
1
2
3
4
5
6
Temp = (char *)strstr(str2, "\"")+1;
Temp2 = (char *)strstr(str2, "><STEAM_");
strncpy(NICK, Temp, Temp2 - Temp);
NICK[Temp2-Temp]='\0';
Temp3 = (char *)strrchr(NICK, '<');
NICK[strlen(NICK) - strlen(Temp3)] = 0;


Geeft schone nick terug. Helaas iets 'rommeliger' dan ik had gehoopt, maar het werkt wel :) Het UID is op een iets eenvoudigere manier gedaan, maar vrijwel gelijk. Die had tenminste een eenzijdig begin en eind. Bedankt voor de hulp iig, en HIGHGuY (en alle anderen), kom wat vaker spelen @ nexus ;)

[ Voor 12% gewijzigd door -W0kk3L- op 26-08-2005 18:10 ]


  • Daos
  • Registratie: Oktober 2004
  • Niet online
-W0kk3L- schreef op vrijdag 26 augustus 2005 @ 18:09:
het ging niet ideaal met sscanf.... dus toch naar een andere manier gezocht. En met een beetje hulp is het gelukt.

code:
1
2
3
4
5
6
Temp = (char *)strstr(str2, "\"")+1;
Temp2 = (char *)strstr(str2, "><STEAM_");
strncpy(NICK, Temp, Temp2 - Temp);
NICK[Temp2-Temp]='\0';
Temp3 = (char *)strrchr(NICK, '<');
NICK[strlen(NICK) - strlen(Temp3)] = 0;


Geeft schone nick terug. Helaas iets 'rommeliger' dan ik had gehoopt, maar het werkt wel :) Het UID is op een iets eenvoudigere manier gedaan, maar vrijwel gelijk. Die had tenminste een eenzijdig begin en eind. Bedankt voor de hulp iig, en HIGHGuY (en alle anderen), kom wat vaker spelen @ nexus ;)
Je kan het het iets minder rommelig maken door mooiere namen te kiezen. "Temp2-Temp" kan je in een variabele stoppen. De casts naar "(char *)" zijn niet nodig en volgens mij is "NICK[strlen(NICK) - strlen(Temp3)] = 0;" hetzelfde als "*Temp3 = '\0';".

Wat gebeurt er als een nickname "><STEAM_" bevat? Of komt dat nooit voor?

[edit]
Code tags en wat spaties en enters helpen ook:
C:
1
2
3
4
5
6
7
8
9
nickStart = strchr(logLine, '\"') + 1;
nickEnd = strstr(logLine, "><STEAM_");
nickLen = nickEnd - nickStart;

strncpy(nick, nickStart, nickLen);
nick[nickLen] = '\0';

nickEnd = strrchr(nick, '<');
*nickEnd = '\0';

[ Voor 19% gewijzigd door Daos op 26-08-2005 19:40 ]


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

-W0kk3L- schreef op vrijdag 26 augustus 2005 @ 18:09:HIGHGuY (en alle anderen), kom wat vaker spelen @ nexus ;)
off-topic:
We hebben zelf 8 servers te onderhouden met UWC3, SH, WC3X enz ;)
hebbie me proggie nou al geprobeerd? of draaien jullie linux... (daar hebben we ook een scriptje voor met gelijke functionaliteit :P

ASSUME makes an ASS out of U and ME


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 15-04 22:07

NMe

Quia Ego Sic Dico.

Daos schreef op vrijdag 26 augustus 2005 @ 19:18:
Wat gebeurt er als een nickname "><STEAM_" bevat? Of komt dat nooit voor?
Dat was inderdaad de reden waarom ik opperde om achteraan te beginnen met lezen en dan puur te kijken naar de tekens < en >. Als TS het op de manier doet die ik omschreef, dan zou het redelijk waterdicht moeten zijn. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • ShadowLord
  • Registratie: Juli 2000
  • Laatst online: 30-04 19:50
Ik zou voor regular expressions gaan. Het logformaat is ontworpen met deze in gedachten, dus waarom afwijken?

Ik heb ergens nog een progje (in C/C++) wat logregels uitleest (met regex). Als je hierin bent geinteresseerd laat me het even weten, dan graaf ik het voor je op.

In ieder geval is deze pagina mischien wel interessant leesvoer:
http://www.hlstats.org/logs/
Deze pagina is het (semi-)officiele document van de log specs.

You see things; and you say, "Why?" But I dream things that never were; and I say, "Why not?"


  • -W0kk3L-
  • Registratie: Juni 2002
  • Laatst online: 20-12-2025
Mijn scriptje is ook gebaseerd op het HLStats idee.. Alleen ik ben niet echt kapot van die perl scripts. Bovendien wil ik dit script niet voor stats maken, maar voor diverse andere doeleinden. De logging loopt ook net zoals HLStats dat doet. Alleen wordt het dus in C geparsed ipv in Perl. Bovendien is het een goeie manier om C te leren, aangezien ik hier pas een paar dagen mee bezig ben :)

Als je dit proggies weet te vinden, ShadowLord, dan heb ik daar zeker interesse in.

[ Voor 13% gewijzigd door -W0kk3L- op 26-08-2005 22:55 ]


  • ShadowLord
  • Registratie: Juli 2000
  • Laatst online: 30-04 19:50
OK, dit is een erg oud progje (2001 ofzo) geschreven voor Linux (console).
Was om HL says in te lezen en zo map votes te doen.. Eigenlijk best gaar progje als ik nu terugkijk :)

Anyhow, je zal het meet geinteresserd zijn in de parselogline functie en de functies die deze aanroept om bepaalde playerdata te laden. Alle regexes zijn gebaseerd op de van het Perl voorbeeld op de website die ik eerder al gaf. Hij kan dan ook alle loglines 'decoden'.

Er is trouwens ook een regex.dll voor Windows ergens die je kan gebruiken en die is compatible met de Linux regexes, dus dat moet lukken. Het is een VS6 project, maar compiled dus niet.

Progje is AS IS. Als je PC affikt omdat er een bug in zit is dat jammer voor je (maar we horen het hier natuurlijk graag terug :) ).

Let ook even op dat VString en VArray GPL code zijn (deze classes gebruik ik zwaar verbeterd in een paar andere projecten). Diti staat niet in de files, maar bij deze dus: GPL code :)

Maar, nu zonder verder gezeur: http://www.hltools.com/files/hlvote.zip

You see things; and you say, "Why?" But I dream things that never were; and I say, "Why not?"


  • -W0kk3L-
  • Registratie: Juni 2002
  • Laatst online: 20-12-2025
Mijn dank is groot! :) Ik zal eens kijken wat ik hier mee kan....
Pagina: 1