Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
April 01, 2005 sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Does anyone know how to make this work properly? The int's are fine, but I can't seem to get the fragger/fragged vars to work properly: <code> int min, sec, pl1, pl2, mod; char[] fragger, fragged; char[] logline = " 59:58 Kill: 0 3 8: pezen killed AEon by MOD_PLASMA"; printf(" Logline: \"%.*s\"\n", logline); sscanf( logline, "%d:%d Kill: %d %d %d: %s killed %s by MOD_PLASMA", &min,&sec,&pl1,&pl2,&mod,&fragger,&fragged ); printf(" Min %d, Sec: %d, Pl1 %d, Pl2: %d, Mod: %2d, Fragger '%.*s', Fragged '%.*s' \n", min,sec,pl1,pl2,mod,fragger,fragged); </code> Yields: Logline: " 59:58 Kill: 0 3 8: pezen killed AEon by MOD_PLASMA" Min 59, Sec: 58, Pl1 0, Pl2: 3, Mod: 8, Fragger 'Error: Access Violation AEon |
April 01, 2005 Re: sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Posted in reply to AEon | On Fri, 01 Apr 2005 06:37:22 +0200, AEon <aeon2001@lycos.de> wrote: > Does anyone know how to make this work properly? The int's are fine, but I can't seem to get the fragger/fragged vars to work properly: > > <code> > int min, sec, pl1, pl2, mod; > char[] fragger, fragged; > > char[] logline = " 59:58 Kill: 0 3 8: pezen killed AEon by MOD_PLASMA"; > printf(" Logline: \"%.*s\"\n", logline); > > sscanf( logline, "%d:%d Kill: %d %d %d: %s killed %s by MOD_PLASMA", > &min,&sec,&pl1,&pl2,&mod,&fragger,&fragged ); > > printf(" Min %d, Sec: %d, Pl1 %d, Pl2: %d, Mod: %2d, Fragger '%.*s', Fragged '%.*s' \n", > min,sec,pl1,pl2,mod,fragger,fragged); > </code> > > Yields: > > Logline: " 59:58 Kill: 0 3 8: pezen killed AEon by MOD_PLASMA" > Min 59, Sec: 58, Pl1 0, Pl2: 3, Mod: 8, Fragger 'Error: Access Violation Remember, sscanf is a C function, it expects a C "char*" not a D "char[]". Try: import std.c.stdio; void main() { int min, sec, pl1, pl2, mod; char[] fragger, fragged; char[] logline = " 59:58 Kill: 0 3 8: pezen killed AEon by MOD_PLASMA"; printf(" Logline: \"%.*s\"\n", logline); //guess at length required fragger.length = 100; fragged.length = 100; sscanf( logline, "%d:%d Kill: %d %d %d: %s killed %s by MOD_PLASMA", &min,&sec,&pl1,&pl2,&mod,fragger.ptr,fragged.ptr ); printf(" Min %d, Sec: %d, Pl1 %d, Pl2: %d, Mod: %2d, Fragger '%.*s', Fragged '%.*s' \n", min,sec,pl1,pl2,mod,fragger,fragged); } Regan |
April 01, 2005 Re: sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath wrote:
> sscanf( logline, "%d:%d Kill: %d %d %d: %s killed %s by MOD_PLASMA",
> &min,&sec,&pl1,&pl2,&mod,fragger.ptr,fragged.ptr );
Thanx... sigh, I had skimmed the metion of .ptr, but had completely forgotten how the naming for C strings works.
Works wonderfully...
Ironically with the above I can save tons of coding I did to manually take the log lines appart. Live and learn or so... :)
AEon
|
April 02, 2005 Re: sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Regan Heath wrote:
> import std.c.stdio;
>
> void main()
> {
> int min, sec, pl1, pl2, mod;
> char[] fragger, fragged;
>
> char[] logline = " 59:58 Kill: 0 3 8: pezen killed AEon by MOD_PLASMA";
> printf(" Logline: \"%.*s\"\n", logline);
>
> //guess at length required
> fragger.length = 100;
> fragged.length = 100;
> sscanf( logline, "%d:%d Kill: %d %d %d: %s killed %s by MOD_PLASMA",
> &min,&sec,&pl1,&pl2,&mod,fragger.ptr,fragged.ptr );
>
> printf(" Min %d, Sec: %d, Pl1 %d, Pl2: %d, Mod: %2d, Fragger '%.*s', Fragged '%.*s' \n",
> min,sec,pl1,pl2,mod,fragger,fragged);
> }
As mentioned in the other post, the above you suggested works wonderfully, but then I wanted to use the sscanf template to print to reconstruct the orgininal log line (primarily to test the sscanf scans):
char[] line = " 59:58 Kill: 0 3 8: pezen killed AEon by ROCKET_SPLASH";
char[] post = " by MOD_ROCKET_SPLASH";
char[] fragger, fragged;
fragger.length = line.length; // Important! Safe case!
fragged.length = line.length;
// Generate proper frag line template on the fly
// e.g. "%d:%d Kill: %d %d %d: %s killed %s by MOD_ROCKET_SPLASH"
char[] templ = "%d:%d Kill: %d %d %d: %s killed %s"~post;
sscanf( line, templ, &min,&sec,&pl1,&pl2,&mod, fragger.ptr,fragged.ptr );
// (1)
fragger = format("%s",fragger).dup;
fragged = format("%s",fragged).dup;
// (2)
writefln(" %s", format(templ, min,sec,pl1,pl2,mod, fragger,fragged) );
printf(" Min %d, Sec: %d, Pl1 %d, Pl2: %d, Mod: %2d, Fragger '%.*s', Fragged '%.*s' Template '%.*s'\n", min, sec, pl1, pl2, mod, fragger, fragged, templ);
The sscanf works. But when I tried to use the templ in a printf like:
printf(templ, min,sec,pl1,pl2,mod, fragger,fragged );
it did not work.
I then tried (2)
writefln(" %s", format(templ, min,sec,pl1,pl2,mod, fragger,fragged) );
using format. That almost works perfectly. Only that fragger and fragged have trailing \0 filling up the strings upto the length line.length.
So the question is how do I turn the C strings fragger/fragged back to proper char[]? I tried something like (1) but that failed.
I find it very strange that the C strings seem to behave like normal D strings printf(" ... %.*s", fragger), and in other cases like C strings.
|
April 02, 2005 Re: sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Posted in reply to AEon | Even when trying to fix the fragger.ptr to a non-zero terminating string manually, the below fails. char[] fr; // = format("%s",fragger).dup; char[] fd; // = format("%s",fragged).dup; foreach( int i, char Ch; fragger ) if( Ch == '\0' ) { fr = fragger[0..i]; fr.length = i; } foreach( int i, char Ch; fragged ) if( Ch == '\0' ) { fd = fragged[0..i]; fd.length = i; } writefln(" %s", format(templ, min,sec,pl1,pl2,mod, fr,fd) ); fr and fd, keep all the trailing \0...hmpf. AEon |
April 02, 2005 Re: sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Posted in reply to AEon | AEon wrote:
> Even when trying to fix the fragger.ptr to a non-zero terminating string manually, the below fails.
>
> char[] fr; // = format("%s",fragger).dup;
> char[] fd; // = format("%s",fragged).dup;
> foreach( int i, char Ch; fragger )
> if( Ch == '\0' )
> {
> fr = fragger[0..i];
> fr.length = i;
> } foreach( int i, char Ch; fragged )
> if( Ch == '\0' )
> {
> fd = fragged[0..i];
> fd.length = i;
> }
> writefln(" %s", format(templ, min,sec,pl1,pl2,mod, fr,fd) );
>
> fr and fd, keep all the trailing \0...hmpf.
Finally, this at least seems to work:
char[] fr; // = format("%s",fragger).dup;
char[] fd; // = format("%s",fragged).dup;
foreach( int i, char Ch; fragger )
if( Ch != '\0' )
fr ~= Ch;
foreach( int i, char Ch; fragged )
if( Ch != '\0' )
fd ~= Ch;
writefln(" %s", format(templ, min,sec,pl1,pl2,mod, fr,fd) );
But I doubt this is the way one handles C strings.
AEon
|
April 02, 2005 Re: sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Posted in reply to AEon | > So the question is how do I turn the C strings fragger/fragged back to proper char[]? I tried something like (1) but that failed.
fragger = fragger[0 .. strlen(fragger.ptr)];
you can find strlen in std.string.
|
April 02, 2005 Re: sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | Ben Hinkle wrote:
>>So the question is how do I turn the C strings fragger/fragged back to proper char[]? I tried something like (1) but that failed.
>
>
> fragger = fragger[0 .. strlen(fragger.ptr)];
> you can find strlen in std.string.
Thanx, works just fine.
AEon
|
April 02, 2005 Re: sscanf() and string "reads" via %s? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Hinkle | On Fri, 1 Apr 2005 20:53:02 -0500, Ben Hinkle <ben.hinkle@gmail.com> wrote:
>> So the question is how do I turn the C strings fragger/fragged back to
>> proper char[]? I tried something like (1) but that failed.
>
> fragger = fragger[0 .. strlen(fragger.ptr)];
> you can find strlen in std.string.
Will this also work:
fragger.length = strlen(fragger.ptr);
Regan
|
Copyright © 1999-2021 by the D Language Foundation