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 ViolationRemember, 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