3

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?

3
  • Could you explain the reason for need this to be a static pointer? Or the purpose of this method (you have told us you need to change something that is static... if it is static it can't change) Commented Sep 13, 2010 at 5:27
  • @Tim Joseph: static is not the same as const. static variables can change. (Nevertheless, using a static variable here is still not a good idea.) Commented Sep 13, 2010 at 8:43
  • Fair point, brain fade... that is what comes from working in c# where all consts are static, but not all statics are const! Commented Sep 14, 2010 at 1:54

6 Answers 6

9

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.

Sign up to request clarification or add additional context in comments.

Comments

7

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.

1 Comment

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.
5

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);
}

Comments

1
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.

Comments

1

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.

Comments

1
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"...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.