我必须手动将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位无符号。
答案 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);
}