switch with string problem
Frits van Bommel
fvbommel at REMwOVExCAPSs.nl
Sun Jul 15 07:30:55 PDT 2007
This sort of stuff should really be posted in digitalmars.D.learn.
Followup-To set (assuming I did it correctly).
qnull wrote:
> I've got a problem with a test program i created. There is a switch with strings inside.
> When I start the program with the argument "t" the result is:
> q = t
> q_len = 116
> default
>
> I don't understand why the program is taking the default branch of the switch and why q.length = 116 and not q.length = 1.
> can somebody give me a hint?
> Thank you
Short version: you're using stuff wrong.
Long version:
> Code:
> import std.string;
>
> import std.stdio;
>
> import std.c.stdlib;
>
>
>
> char[] q;
A char[] in D contains a length and a pointer. IIRC both DMD and GDC put
them in memory in that order.
> int main(char[][] args)
>
> {
>
> if (args.length == 2) {
>
> sscanf(&args[1][0],"%s",&q);
Here you're basically telling sscanf to copy the first parameter to &q.
Unfortunately, &q is the address of the (length, ptr) pair, not the
pointer itself. This compiles because C-style variadic functions like
sscanf and printf can't check the types of the variadic parameters.
The simplest correct way to copy the first parameter to q would be "q =
args[1].dup;" (That also allocates storage for the copy, something you
forgot to do)
>
> }
>
> else {
>
> printf("just one argument!\n");
You really shouldn't be using printf in D. You imported std.stdio, so
why aren't you using writef[ln]?
>
> exit(55);
>
> }
>
> printf("q = %s\nq_len = %d\n",&q,q.length);
The first format sequence + parameter tell printf to read a string from
&q (which is what sscanf put there, but not what D would consider to be
the contents of the array)
q.length is the first four bytes (on a 32-bit system) of &q. Those
contain 't', \0, \0, \0 (the latter two were how they were initialized
at program startup, the first two were put there by your wrong use of
sscanf. q.ptr is still null (as initialized on startup).
> switch (q)
Here you're inspecting the contents of an array with .length == 116 (the
ASCII character code for 't') and .ptr == null. The only reason you're
not segfaulting on the null pointer is that the code that implements the
string switch checks that the length is equal before checking that the
content is equal, and so never actually dereferences the null because
the only options it's comparing against are a length-1 and a length-2
string.
>
> {
>
> case "t": printf("arg was t!\n"); break;
>
> case "l2": printf("arg wasn't t!\n"); break;
>
> default: printf("default\n"); break;
>
> }
>
> return 0;
>
> }
>
>
>
> compiled with gdc 0.23
More information about the Digitalmars-d-learn
mailing list