麻烦使用sprintf()

时间:2013-12-19 20:17:15

标签: c string linked-list

我正在使用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()问题?

3 个答案:

答案 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);