digitalmars.D.learn - sscanf() and string "reads" via %s?
- AEon <aeon2001 lycos.de> Mar 31 2005
- "Regan Heath" <regan netwin.co.nz> Mar 31 2005
- AEon <aeon2001 lycos.de> Mar 31 2005
- AEon <aeon2001 lycos.de> Apr 01 2005
- AEon <aeon2001 lycos.de> Apr 01 2005
- AEon <aeon2001 lycos.de> Apr 01 2005
- "Ben Hinkle" <ben.hinkle gmail.com> Apr 01 2005
- AEon <aeon2001 lycos.de> Apr 01 2005
- "Regan Heath" <regan netwin.co.nz> Apr 01 2005
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
Mar 31 2005
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
Mar 31 2005
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
Mar 31 2005
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.
Apr 01 2005
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
Apr 01 2005
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
Apr 01 2005
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.
Apr 01 2005
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
Apr 01 2005
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
Apr 01 2005









AEon <aeon2001 lycos.de> 