我正在使用sprintf
将int转换为字符串。然后我将字符串传递给函数“enqueue”。此函数接受字符串并将其插入FIFO链接列表。问题是,当我使用显式字符串调用enqueue()
时,它可以正常工作,但是当我使用sprintf
字符串缓冲区调用它时,它会以某种方式覆盖已经存在于队列中的元素。
typedef struct
{
char *movie;
char *pkt;
} packet ;
struct node
{
packet page;
struct node *next;
} *front= NULL, *rear=NULL;
void display_fifo(){
struct node *t;
t=front;
while ((front==NULL)|| (rear==NULL))
{
printf("\nempty fifo\n");
return ;
}
while (t!=NULL)
{
printf("->%s\t %s\n", t->page.movie, t->page.pkt);
t= t-> next;
}
}
void enqueue(char * movie, char *pkt)
{
packet new;
new.movie= movie;
new.pkt=pkt;
struct node *p;
p= (struct node*)malloc(sizeof(struct node));
p->page= new;
p->next= NULL;
if (rear== NULL|| front ==NULL)
front=p;
else
rear->next=p;
rear=p;
}
void main(){
char buff[10];
int i;
for (i=1;i<=5;i++){
sprintf(buff, "%d", i);
enqueue("1", buff);
printf("***\n");
display_fifo();
}
}
我为上面写的代码得到的输出:
*** ->1 1 *** ->1 2 ->1 2 *** ->1 3 ->1 3 ->1 3 *** ->1 4 ->1 4 ->1 4 ->1 4 *** ->1 5 ->1 5 ->1 5 ->1 5 ->1 5
是否有sprintf
的替代方法可以返回我应该使用的char指针,还是我的enqueue()
问题?
答案 0 :(得分:4)
问题是您始终重复使用相同的缓冲区。通过引用buff
总是得到相同的指针,所以你要继续覆盖你的字符串。
您可以使用malloc
创建新缓冲区,或者使用非标准GNU扩展asprintf
(在Linux系统和Mac OS X上至少可用,但肯定不是Windows)分配必要的记忆。在这两种情况下,当你完成指针时,你需要free
指针。
此外,您应该避免使用sprintf
并使用snprintf
来保护程序免受缓冲区溢出的影响。 (如果您不知道缓冲区的大小,我会建议您不要使用sprintf
。)
对asprintf
的调用如下所示:
char* buffer;
asprintf(&buffer, "%d", i);
// do stuff with buffer; it now points to a number string
free(buffer);
malloc
+ snprintf
稍微复杂一些,因为您需要确定要分配的缓冲区的大小:
char* buffer;
int i, allocSize;
// log10(number) is the digit count in `number` minus one, so
// we add two to account for the null terminator
allocSize = log10(i) + 2;
buffer = malloc(allocSize * sizeof *buffer);
snprintf(buffer, allocSize, "%d", i);
// do stuff with buffer; it now points to a number string
free(buffer);
答案 1 :(得分:1)
您的packet
正在存储指向字符的指针,而不是字符本身。指针始终指向buff
。
使用malloc一些内存来保存字符,或者将make pkt
添加为char
的数组。
答案 2 :(得分:1)
问题是你使用char * buff并在你的enqueue函数中复制指针!
new.pkt=pkt;
这是错误的,每次更改buff时,所有其他节点值都会更改,因为它们都引用相同的缓冲区。 你必须改变这一行!
new.pkt = pkt;
与
new.pkt = malloc(strlen(pkt));
strcpy(new.pkt,pkt);