digitalmars.D.learn - sscanf() and string "reads" via %s?
- AEon (18/18) Mar 31 2005 Does anyone know how to make this work properly? The int's are fine, but...
- Regan Heath (21/38) Mar 31 2005 Remember, sscanf is a C function, it expects a C "char*" not a D "char[]...
- AEon (7/9) Mar 31 2005 Thanx... sigh, I had skimmed the metion of .ptr, but had completely
- AEon (33/54) Apr 01 2005 As mentioned in the other post, the above you suggested works
- AEon (21/21) Apr 01 2005 Even when trying to fix the fragger.ptr to a non-zero terminating string...
- AEon (14/36) Apr 01 2005 Finally, this at least seems to work:
- Ben Hinkle (2/4) Apr 01 2005 fragger = fragger[0 .. strlen(fragger.ptr)];
- AEon (3/9) Apr 01 2005 Thanx, works just fine.
- Regan Heath (4/8) Apr 01 2005 Will this also work:
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:Thanx, works just fine. AEonSo 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
On Fri, 1 Apr 2005 20:53:02 -0500, Ben Hinkle <ben.hinkle gmail.com> wrote:Will this also work: fragger.length = strlen(fragger.ptr); ReganSo 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









AEon <aeon2001 lycos.de> 