[英]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)根据现有的argv
和argc
参数确定数组大小信息。
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.