如何在C中手动将环境值设置为整数零

时间:2014-01-04 02:19:48

标签: c linux

  

我必须手动将ENVIRONMENT的值初始设置为整数0。    通过以下函数,我将尝试检索它并将其再次设置为deisred值。

int abcd()
{
    int temp1=0,temp2;
    temp1++;
    char *env=NULL;
    env=getenv("ENVIRONMENT");
    sscanf(env,"%d",&temp2);
    temp2=temp2+temp1;
    printf("%d",temp2);
    sprintf(temp2,"%d",env);
    setenv("ENVIRONMENT",env,0);
}
  

所有整数变量都是32位无符号。

1 个答案:

答案 0 :(得分:3)

让我们看看gcc的想法

nil.c:12:1: warning: passing argument 1 of ‘sprintf’ makes pointer from integer without a cast
nil.c:12:1: note: expected ‘char *’ but argument is of type ‘int’


   sprintf(temp2,"%d",env);
           ¯¯¯¯¯      ¯¯¯

看起来它说你的论点是错误的类型。什么是sprintf的手册页?

  int sprintf(char *str, const char *format, ...);

嗯。我打赌你以为你想这样做......

  sprintf (env, "%d", temp2);

但等等...... env指向的缓冲区有多大?它是否适合temp2可能包含的所有可能值以及强制\0终结符?

getenv手册说:

   RETURN VALUE

   The  getenv() function returns a pointer to the value in the environment, or NULL
   if there is no match.

Uh'oh。 “在环境中!”我们可能不应该写那个缓冲区!

   BUGS

   Because sprintf() and vsprintf() assume an arbitrarily long string, callers  must
   be  careful not to overflow the actual space; this is often impossible to assure.
   Note that the length of the strings produced is locale-dependent and difficult to
   predict.    Use   snprintf()   and   vsnprintf()   instead  (or  asprintf(3)  and
   vasprintf(3)).

哦,asprintf听起来像个好主意......

   int asprintf(char **strp, const char *fmt, ...);

   DESCRIPTION

   The   functions   asprintf()  and  vasprintf()  are  analogs  of  sprintf(3)  and
   vsprintf(3), except that they allocate a string large enough to hold  the  output
   including  the  terminating  null  byte, and return a pointer to it via the first
   argument.  This pointer should be passed to  free(3)  to  release  the  allocated
   storage when it is no longer needed.

   RETURN VALUE

   When  successful,  these  functions return the number of bytes printed, just like
   sprintf(3).  If memory allocation wasn't possible, or some  other  error  occurs,
   these functions will return -1, and the contents of strp is undefined.

EDITED: 在回应评论时,我没有注意到这个其他错误:

   DESCRIPTION
   The  setenv()  function  adds the variable name to the environment with the value
   value, if name does not already exist.  If name does exist  in  the  environment,
   then its value is changed to value if overwrite is nonzero; if overwrite is zero,
   then the value of name is not changed.  This function makes copies of the strings
   pointed to by name and value (by contrast with putenv(3)).


  setenv ("ENVIRONMENT", "0", 0);
                              ¯ 

您可能还想启用覆盖值。

我本来鼓励你自己重构一下,但是把编译器和手册所说的放在一起,我们得到:

int abcd()
{
    /* Set up automatic variables with default values */
    const int temp1 = 1;
    int env_value = 0;
    char *old_env = NULL;
    char *new_env = NULL;

    /* Let's see if this is set in the environment */
    old_env = getenv ("ENVIRONMENT");
    /* Was it set? And, if so, can we get a decimal integer from it? */
    if (NULL != old_env 
        && 1 == sscanf (old_env, "%d", &env_value)) {
            /* OK, both library functions succeeded, so let's increment… */
            env_value += temp1;
    }
    /* Log the output */    
    printf ("new env value = %d\n", env_value);
    /* Let's allocate a new buffer and write the string version of
     * this number to it */
    asprintf (&new_env, "%d", env_value);
    /* Note … forgot to check success of asprintf!
     * Correcting this bug left as an excercise to the reader. */

    /* Copy the new value into the environment, overwriting if necessary */
    setenv ("ENVIRONMENT", new_env, !0);
    /* Clean up that buffer! */
    free (new_env);
}