简体   繁体   English

使用sprintf()将整数保存到字符串数组中

[英]Saving an integer into an array of strings using sprintf()

I'm having trouble storing an integer into an array of strings using sprintf(). 我在使用sprintf()将整数存储到字符串数组时遇到麻烦。 I am trying to create a new argv list to pass into my child process. 我正在尝试创建一个新的argv列表以传递到我的子进程中。 I have 'curr' storing the correct value since I've tested in in GDB. 自从我在GDB中进行测试以来,我已经“ curr”存储了正确的值。 My code is as follows: 我的代码如下:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h> /* for pid_t */

int main(int argc, char *argv[]){

static char *argv2[] = {"./datagen", "10", "outputfile", "SIGUSR1"};

pid_t pid = fork();
int curr = getpid();
sprintf(argv2[4], "%s", curr);


if(pid == 0)
{
    printf("You are in the child process.\n");

}
else{
    printf("You are in the parent process.  Process ID is %d\n", getpid());
}


return;
}

After exhaustively searching around for a clear answer, I have yet to find anything. 在详尽地寻找一个明确的答案之后,我还没有找到任何东西。 Ideally, the 4th slot of argv2 will store the process id as a string. 理想情况下,argv2的第4个插槽将进程ID作为字符串存储。 However, I am getting a segmentation fault 11. If anyone could shed some light on this issue I would be eternally grateful. 但是,我遇到了细分错误11。如果有人可以阐明这个问题,我将永远感激不已。

Thank you!! 谢谢!!

You can't do that 你不能那样做

static char *argv2[] = {"./datagen", "10", "outputfile", "SIGUSR1"};

is a declaration of an array of char pointers, which are pointing to string literals, and further more to four string literals only, you can't extend it nor modifiy the strings. 是一个char指针数组的声明,该char指针指向字符串文字,并且仅指向四个字符串文字,您不能扩展它也不能修改字符串。

What you need is 您需要的是

char argv2[10][100] = {"./datagen", "10", "outputfile", "SIGUSR1"};

assuming that you want 10 strings of maximum length 100 , which you can obviously change. 假设您想要10个最大长度为100字符串,那么您显然可以更改。

Also, the format specifier for integers is "%d" so you have another mistake, having said all that you can now 另外,整数的格式说明符为"%d"因此您又犯了一个错误,说了所有您现在可以做的

sprintf(argv2[4], "%d", curr);

and I would suggest the snprintf() function, since it will avoid buffer overflow problems, 我建议使用snprintf()函数,因为它将避免缓冲区溢出问题,

snprintf(argv2[4], sizeof(argv[4]), "%d", curr);

chux comment is correct if you want to have control on whether the specified length of the string was enough, you should check the return value of snprintf() , in case there wasn't sufficient space to write all the source string into the destination it will be truncated, if snprintf() returns a value larger or equal to the requested maximum, it means that the string was truncated, so a simple check like 如果要控制字符串的指定长度是否足够, chux注释是正确的,如果没有足够的空间将所有源字符串写入目标字符串,则应检查snprintf()的返回值。将被截断,如果snprintf()返回的值大于或等于所请求的最大值,则意味着该字符串已被截断,因此可以进行简单的检查,例如

if (snprintf(argv2[4], sizeof(argv[4]), "%d", curr) >= sizeof(argv[4]))
    doSomething_TheString_Was_Truncated();

although, for 100 characters and the "%d" that will not happen, but I firmly believe that people must write safe code as a habit, rather than only checking possible problems, check for every thing that can conceptually go wrong, no matter how unlikely. 尽管对于100字符和不会出现的"%d"字符,我坚信人们必须以习惯的方式编写安全的代码,而不是仅检查可能的问题,而不要检查概念上可能出错的每件事不太可能。 Because sometimes there will be situations where an unexpected thing will happen. 因为有时在某些情况下会发生意想不到的事情。

Note : as chux pointed out again, snprintf() will return a negative in case of an error, you can check for that separately, to check if there was an error. 注意 :正如chux再次指出的那样,如果出现错误, snprintf()将返回负数,您可以单独检查该值,以检查是否有错误。

Simple steps: 简单步骤:
1) Determine array size information from existing argv , argc arguments. 1)根据现有的argvargc参数确定数组大小信息。

int i, len=0, lenKeep=21;//initialize large enough to contain pid integer
for(i=0;i<argc;i++)
{
    len = strlen(argv[i])
    if(lenKeep<len)lenKeep = len;
}  

2) use that size information to create a new string array, argv2 , with additional elements if necessary. 2)使用该大小信息创建一个新的字符串数组argv2 ,如有必要,还可以使用其他元素。 (argv2 will be an array of strings, create sufficient space.) (argv2将是一个字符串数组,创建足够的空间。)

char argv2[argc+1][lenKeep+1];    
//argc+1 allows for additional array element
//lenKeep+1 provides space for all existing content  

3) add new information to the string array in the normal way. 3)以正常方式将新信息添加到字符串数组。

sprintf(argv2[argc], "%d", curr); //argv2 array contains argc + 1 elements 
                                  //so now argc is a valid index value

sprintf(argv2[4], "%s", curr); breaks the array, which has only 4 elements. 中断只有四个元素的数组。

Even if it has more elements, you are writing to a string literal which is Undefined Behaviour. 即使它包含更多元素,您仍在写入字符串文字,即Undefined Behaviour。

尝试使用%d代替%s,无论如何它应该另存为C字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM