tags:

views:

235

answers:

6

Help me out, gurus

/*
 * In this function, I want the static variable position to point to next element
 * of the str, every time I call this function.
 */
void function(char *str){

   static char *position = str;

   /* Do something here to this position */

   position += 1;
 }

The purpose of this program is to do string substitution, every time I substituted a pattern of the str I have to let the static position variable point to a new position of the str, and then I will copy every thing into another new string.

The problem is, the compiler keep telling me "the initializer element is not a constant", how can I fix this?

+9  A: 

You can't have a static variable in your function to point to the next element of str, because position is a global variable that is initialized once, and str may have different value every time you call a function.

What you need here is a loop that iterates over str,

void func1(char *str) {
    char *p;
    for (p = str; /* some condition here */; ++p) {
        /* Do something here to this position */
    }
}

or have a loop outside this function and pass str incremented by 1 every iteration.

void func1(char *str) {
    /* Do something here to this position */
}

void func2() {
    char *str = ...;
    ...
    char *p;
    for (p = str; /* some condition here */; ++p) {
        func1(p);
    }
}

Of course, you can initialize a static to NULL first and use it to check if you started iterating over str, but that's poor style: too stateful and error prone, not reentrant and not thread-safe.

Alex B
+7  A: 

What you need to do is find some way to decide if you're at the beginning of the string, in which case you reset position, or not, in which case you increment it:

/*
 * In this function, I want the static variable position to point to next element
 * of the str, every time I call this function.
 */
void function(char *str){

   static char *position;

   if (str) {
       position = str;
   } else {
       /* Do something here to this position */
       position += 1;
   }
 }

Now when str is NULL, the function assumes that you're continuing to work with the same string as before, and when it's not NULL, it assumes that you're working with a new string.

Nathan Fellman
Note that this is the same mechanism as used by the standard library routine `strtok()` to choose between beginning an iteration and continuing the current iteration. It has the difficulties that it cannot be nested, and it is not threadsafe. However if you only require one iteration at a time in a single processes, this is the way to do it.
RBerteig
+5  A: 

This isn't really the C way of doing things - it isn't re-entrant for a start -but if you absolutely must:

/*
 * In this function, I want the static variable position to point to next element
 * of the str, every time I call this function.
 */
bool function(char *str){

   static char *last_str;
   static char *position;

   if (str != last_str)
       last_str = position = str;

   /* Do something here to this position */

   if (*position != '\0')
       ++position;
   else
       last_str = NULL;

   return *position != '\0';
 }

You can then do things like:

while (more) {
   // do something
   more = function(string);
}
Dipstick
+1  A: 
static char *position = str;

The real reason behind this error is that since position is as a global variable it can only be initialized with a compile time constant. You'll get the same error if you try

#include <stdio.h>
int j = 9;
static int k = j + 3; /* Error */
int main(){}

Both j and str are not compile time constants, hence the error.

Amarghosh
+1  A: 

As others have mentioned, using a static variable here is a bad idea. I will elaborate a bit on the error however:

In C, variables with static storage duration (global variables and static variables) are initialized before program startup. This therefore requires that the initial values be known ahead of time and must be compile-time constants.

It's a bit different in C++, and perhaps this is the behavior you're expecting. Variables with static storage duration there may be initialized dynamically. For global variables, this means in some unspecified order during program startup; for static variables within functions, this means that they are initialized when the function is first executed.

jamesdlin
+1  A: 
void func1();

char str[10] = "good";

int main()
{
   func1();
   return 0;    
}

void func1()
{
   static char *pos = &str[0];

   pos++;

   (pos) ? printf("%s\n",pos) : 0;  
}

This program will do. I wrote the string in global area with ReadWrite region that is global initialization region and assign the starting address of the string inside the function. first call print "ood", second call print "od"...

Muthuraman