2011-12-19 54 views
0

我只允许使用下列头scanf函数的char *字结构只显示最后输入

#include <stdio.h> 
#include <stdlib.h> 

,我定义我的struct student如下:

struct dict 
{ 
    char* word; 
    struct dict* link; 
}; 

有很多功能,但只有一个功能,我现在有问题。 该函数在链接的末尾插入一个结构字典,并带有某个名称。

struct student *Linsert(struct dict *list, char *name) 
{ 
    struct student *pnew; 
    struct student *pn; 
    int exist = 1; 

    pnew = (struct dict *)malloc(sizeof(struct dict)); 
    pnew -> next = NULL; 
    pnew -> name = name; 

    if (list != NULL) 
    { 
     for (pn = list; pn -> next != NULL; pn = pn -> next) ; 
     pn -> next = pnew; 
    } 
    else 
     list = pnew; 

    return list; 
} 

使用下面的函数,

//print all the values in the list 
void printList(struct dict* list); 

我这样做:

int main(void) 
{ 

    struct dict *list = NULL; 

    char *name; 

    while (1) { 
     scanf("%s", name); 
     if (name == 'Q') 
      break; 

     list = Linsert(list, name); 
     printList(list); 
    } 
    return 0; 
} 

比方说输入,我输入3 applebananaorange,我的结果显示了我最后的三个输入。

这里有什么问题?

+1

始终用**所有警告**进行编译,并且不要忽略其中的任何警告。 –

+0

请看看[如何格式化您的问题](http://stackoverflow.com/editing-help),特别是下一次如何格式化代码块。 –

+0

@KerrekSB'-Wall -Wextra -Werror'总是会导致更好的代码':)' –

回答

2

main片断就有问题一大堆:

  • name是未初始化的指针;它指向你尚未分配并允许使用的内存中未知的位置,因此导致未定义的行为。也许你想char name[20]在栈上分配一个20个char的数组,并且有scanf在这个缓冲区中存储输入。

  • 你一个char*(一个指向字符串的开始)与单个char'Q' - 你要比较一个指针和一个整数值作为你的编译器警告会告诉你。您没有为字符串'Q'的值比较字符串的内容,而是将内存地址name'Q'的整数值进行比较。如果你想字符串name以字符串"Q"比较,使用strcmp并为您的0

返回值,你也想被做传递给Linsert变量的副本,否则,当你”我们注意到,每次你都会传递一个指向内存中相同位置的指针,而对这块内存的改变会改变你的每个项目。

如果你把你的编译器警告起来,你会得到更多的警告。

1

您没有为该名称分配任何内存,因此scanf正在写入一些随机位置,并且每次都通过循环覆盖它。

1

一个问题是,您尚未为word成员分配存储以指向该存储。您还没有为name指定空间。这是麻烦的主要原因。

您需要为name分配空间;最简单的方法是:

char name[128]; 

您需要分配空间来存储的话,你需要的name内容复制到word这样,当下一行覆盖name,它不破坏保存word

适应你的代码,你可以使用:

struct student *Linsert(struct dict *list, char *name) 
{ 
    struct student *pnew; 
    struct student *pn; 

    pnew = (struct dict *)malloc(sizeof(struct dict)); 
    if (pnew == 0) 
     ...error... 
    pnew->next = NULL; 
    pnew->word = malloc(strlen(name) + 1); 
    if (pnew->word == 0) 
     ...error... 
    strcpy(pnew->word, name); 

    if (list != NULL) 
    { 
     for (pn = list; pn->next != NULL; pn = pn->next) 
      ; 
     pn->next = pnew; 
    } 
    else 
     list = pnew; 

    return list; 
} 

不要忽略对内存分配错误检查 - 痛苦的,虽然它是。当你忘记时它会咬你。

在风格上,不要在->.附近使用空格;他们是非常紧密结合的运营商,他们不应该像其他二元运营商一样分开。

有一个方便的功能,strdup(),重复一个字符串,但它不是标准的C(它是标准的POSIX)。

3

我看到两个问题与您的代码:

  • 你需要传递一个scanf阵列char大小足以存储输入字符串的,不是简单的字符指针。
  • 您需要将传入的字符串复制到Linsert(使用strdup)。
0

由于name是一个字符指针,因此您对每个dict结构的字段的赋值将使用它指向的最新值。