Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Logic & switch statement 1

Status
Not open for further replies.

DaRedMonkey

IS-IT--Management
Aug 23, 2002
17
US

I got the following code and it gave me the following error: line 121: error 1549: Modifiable lvalue required for assignment operator

Here's the code snippet:


char lot_prefix[2], proddir[20]

strncpy(lot_prefix, lot_no, 2);

if ( (strncmp(lot_prefix[1],"F",1) == 0) || (strncmp(lot_prefix[1],"I",1) == 0) || (strncmp(lot_prefix[1],"L",1) == 0) )
{
proddir = "Food";
} else if ( (strncmp(lot_prefix[1],"D",1) == 0) || (strncmp(lot_prefix[1],"G",1) == 0) || (strncmp(lot_prefix[1],"P",1) == 0) )
{
proddir = "Garden";
} else if ( (strncmp(lot_prefix[1],"E",1) == 0) || (strncmp(lot_prefix[1],"J",1) == 0) || (strncmp(lot_prefix[1],"M",1) == 0) )
{
proddir = "Automotive";
} else if ( (strncmp(lot_prefix[1],"K",1) == 0) || (strncmp(lot_prefix[1],"R",1) == 0) )
{
proddir = "Electronic";
} else if ( (strncmp(lot_prefix[1],"T",1) == 0) )
{
proddir = "Book";
} else
{
print "Sorry, You need to add the new product to the program before you can use it. \n";
}


I also tried to do it using switch-case statement but also having problem:


switch (lot_prefix[1]) {
case 'P':
proddir = "Food";
break;
case 'I':
proddir = "Garden";
break;
case 'T':
proddir = "Automotive";
break;
case 'F':
proddir = "Electronic";
break;
default:
proddir = "other";
}


Also, Can I do this with the case statement? case 'T|V|K' or can I do this case 'T' | 'V' | 'K'

I remember vaguely that you can do something like that.

--DRM
 
declare your variable as...

char *proddir;

...the compiler is complaining about the fact that
you are assigning a predefined array "proddir[20]"
to a constant (which is stored on the heap). This does
not copy the data it just tries to reassign the
pointer to the memory allocated for the array. This
is incorrect and should not compile. Declaring it as a
character pointer should do what you want.

Best regards
 

Thank you for your suggestion.

I tried
strcpy(proddir,"Food");

instead of
proddir = "Food";

and everything worked as expected.

--DRM
 
The closest you can come is to use multiple case statements and take advantage of "fall-through":

case 'T': case 'V': case 'K':
/* do something */
break;

If you don't plan on modifying the contents of proddir, you can do what rwb suggested and change proddir to a pointer and keep the assignments the same as you have them in the above code fragment.
 

I tried rwb1959's suggestion by using... char *proddir;

instead of... char proddir[20];

and got a core dump.

--DRM

 
Which bit of code are you trying?

This for example won't compile without errors, given the current declarations
Code:
>         if ( (strncmp(lot_prefix[1],"F",1) == 0) || (strncmp(lot_prefix[1],"I",1) == 0) || (strncmp(lot_prefix[1],"L",1) == 0) )

lot_prefix is a char array, lot_prefix[1] is a char.
strncmp() expects a pointer to a char, so
Code:
        if ( (strncmp(&lot_prefix[1],"F",1) == 0) || (strncmp(&lot_prefix[1],"I",1) == 0) || (strncmp(&lot_prefix[1],"L",1) == 0) )
would be correct

However, comparing a single char is a lot of overhead, so you could do this
Code:
        if ( lot_prefix[1] == 'F' || lot_prefix[1] == 'I' || lot_prefix[1] == 'L' )

Using a switch/case statement, you would have
Code:
char lot_prefix[2], *proddir;
    strncpy(lot_prefix, lot_no, 2);
    switch (lot_prefix[1]) {
          case 'F':
          case 'I':
          case 'L':
                proddir = "Food";
                break;
          default:
                printf("Sorry, You need to add the new product to the program before you can use it. \n");
                break;
    }
 
What part of the code gave you a core dump?
I assume that it may be later on (after the switch)
when you are actually using "poddir". Your code may
require "writable" space at "proddir" in which case
char *proddir = "Food"; will point to "read-only" space
and therefore cannot be used. Your solution of the
strcpy(proddir, "Food"); is perfectly acceptable.
In this case, you may want to consider initializing
the array before the "switch"...

memset((void *)proddir, '\0', sizeof(proddir));
 
You would use "memset" to initialize the memory
allocated by the statement...

char proddir[20];

...since this is declared inside "main()", it
is local in scope and allocated on the stack.
These types of variables (automatic) are not
initialized and it is always good programming
practice to initialize variables before use.
 
It's certainly debatable if an initialization constitutes "good programming practice" in all instances, particularly if that initialization constitutes a hit on runtime performance.
 
Initializing un-initialized variables before use is good
practice in all instances. If you really feel the memset
will give you a performance hit then you should design
your code so that your variable is initialized at compile time
(global) or in the declaration or use pointers.
However, the call to memset that one time will probably add
3 CPU instruction cycles to the entire process.

You of course are free to continue to not initialize
but when your subsystem is up around 10K or 20K lines
of code, enjoy debugging it.

 
I've never had a problem with not initializing everything, even when the codebase becomes as large as you mention. I don't personally think that the trade-off of changing a declaration to file scope (which reduces program integrity and tends to increase bugs as the variable can now be modified from places other than the function in which it is needed) just for the sake of ensuring that a value is initialized is worth it.

The size of the object being initialized, the speed of the processor (don't forget embedded systems), the frequency that the initialization is performed (how often the function is called) and the project requirements are some of the things that will determine whether or not that memset will be worthwhile or not.

Don't get me wrong, intialization is a *good* thing, generally. I just wanted to point out that it is not *always* best practice.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top