将字符串与链接列表数据元素进行比较时,strcmp不会返回0

时间:2019-05-04 20:51:42

标签: c linked-list strcmp

我在使用链表程序时遇到了麻烦,在该程序中,strcmp从不返回0,但是它们相等。我尝试使用strcpy()函数将temp-> name放在字符串中,但是它也不起作用。我正在尝试将平均值分配给temp-> average。

以下是输入内容:

vloz Mrkvicka Jozko 1 1.25
vloz Hrusticka Ferko 2 1.5
vloz Kalerab Jurko 1 2.14
vloz Hrusticka Ferko 1 2.8
vloz Zeler Misko 1 4.12
vypis
zmen Hrusticka Ferko 3.0
vypis

我的输出应如下所示:

firstname=Zeler, name=Misko, year=1, average=4.12
firstname=Hrusticka, name=Ferko, year=1, average=2.80
firstname=Kalerab, name=Jurko, year=1, average=2.14
firstname=Hrusticka, name=Ferko, year=2, average=1.50
firstname=Mrkvicka, name=Jozko, year=1, average=1.25

firstname=Zeler, name=Misko, year=1, average=4.12
firstname=Hrusticka, name=Ferko, year=1, average=3.00           //current 2.80
firstname=Kalerab, name=Jurko, year=1, average=2.14
firstname=Hrusticka, name=Ferko, year=2, average=3.00           //current 1.50
firstname=Mrkvicka, name=Jozko, year=1, average=1.25

我当前的输出:

firstname=Zeler, name=Misko, year=1, average=4.12
firstname=Hrusticka, name=Ferko, year=1, average=2.80
firstname=Kalerab, name=Jurko, year=1, average=2.14
firstname=Hrusticka, name=Ferko, year=2, average=1.50
firstname=Mrkvicka, name=Jozko, year=1, average=1.25

firstname=Zeler, name=Misko, year=1, average=4.12
firstname=Hrusticka, name=Ferko, year=1, average=2.80 
firstname=Kalerab, name=Jurko, year=1, average=2.14
firstname=Hrusticka, name=Ferko, year=2, average=1.50
firstname=Mrkvicka, name=Jozko, year=1, average=1.25

这是我的完整代码:

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

struct student
{
  char firstname[50];
  char lastname[50];
  int year;
  double average;
  struct student *next;
};

struct database
{
  struct student *first;
};

struct database *create_head ()
{
  struct database *head = (struct database *)malloc(sizeof(struct database));
  head -> first = NULL;
  return head;
}

void vloz (struct database *head)
{
  struct student *temp = (struct student *) malloc (sizeof(struct student));
  temp -> next = NULL;

  char firstname[50];
  char lastname[50];
  int year;
  double average;

  scanf("%s %s %d %lf\n", firstname, lastname, &year, &average);
  strcpy(temp -> firstname, firstname);
  strcpy(temp -> lastname, lastname);
  temp -> year = year;
  temp -> average = average;

  temp -> next = head -> first;
  head -> first = temp;
  return; 

}

void zmen (struct database *head)
{
  char firstname[50];
  char lastname[50];
  double average;
  scanf("%s %s %lf", lastname, firstname, &average);

  struct student *temp =  head -> first;

  while (temp != NULL)
  {
    if (strcmp(temp -> firstname, firstname) == 0)
    {
      printf("TTT\n");
      temp -> average = average;
    }

    temp = temp -> next;
  }
}

void vypis (struct database *head)
{
  struct student *temp = head -> first;
  while (temp != NULL)
  {
    printf("lastname=%s, firstname=%s, year=%d, average=%.2lf\n", temp -> firstname, temp -> lastname, temp -> year, temp -> average);
    temp = temp -> next;
  }
  printf("\n");
}


int main()
{
  char prikaz[20];
  struct database *head = create_head();
  while (scanf("%s", prikaz) > 0)
  {
    if (strcmp(prikaz, "vloz") == 0)
    {
      if (head->first != NULL)
      {
        struct database *head = create_head();
      }
      vloz (head);
    }

    if (strcmp(prikaz, "vypis") == 0)
      vypis (head);

    if (strcmp(prikaz, "zmen") == 0)
      zmen (head);


  }

  return 0;
}

2 个答案:

答案 0 :(得分:2)

您切换了名字和姓氏,因此比较不起作用。

在vloz中,它看起来像这样:

scanf("%s %s %d %lf\n", firstname, lastname, &year, &average);

在zmen中,scanf的第一个元素是姓氏:

scanf("%s %s %lf", lastname, firstname, &average);

如果您在zmen中切换顺序,则看起来像这样:

scanf("%s %s %lf", lastname, firstname, &average);

您将获得预期的输出。

调试输出

使用正确的顺序时,调试控制台中的输出看起来像预期值:

debug output

答案 1 :(得分:0)

发布的代码存在一些问题,但是没有任何东西可以解释您的观察结果。

问题必须出在其他地方,即您编写的用于解析文件和构造列表的函数中。将完整的代码发布到表现出意外行为的工作程序中。

这是您的代码中的一些问题:

  • 您应始终对scanf()的返回值进行修改,以检测到文件末尾的无效输入。
  • 您应该删除scanf("%s %s %d %lf\n", firstname, lastname, &year, &average);中的尾随换行符,这会使scanf()继续读取,直到获得非空输入为止。
  • 使用以下命令读取字符串时,应防止缓冲区溢出:

    scanf("%49s %49s %lf", lastname, firstname, &average);
    
  • 测试if (head->first != NULL) { struct database *head = create_head(); }没有用:如果列表不为空,则将新树分配给新的局部变量,该局部变量立即超出范围。

  • 您在扫描功能中没有正确比较名称。

  • 请为您的功能使用英文名称,请耐心等待。

这是修改后的版本:

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

struct student {
    char firstname[50];
    char lastname[50];
    int year;
    double average;
    struct student *next;
};

struct database {
    struct student *first;
};

struct database *create_head(void) {
    struct database *head = malloc(sizeof(struct database));
    head->first = NULL;
    return head;
}

void vloz(struct database *head) {
    struct student *temp = malloc(sizeof(struct student));
    if (temp == NULL) {
        printf("out of memory\n");
        return;
    }

    char firstname[50];
    char lastname[50];
    int year;
    double average;
    if (scanf("%49s %49s %d %lf", firstname, lastname, &year, &average) != 4) {
        printf("invalid input\n");
        return;
    }
    strcpy(temp->firstname, firstname);
    strcpy(temp->lastname, lastname);
    temp->year = year;
    temp->average = average;
    temp->next = head->first;
    head->first = temp;
}

void zmen(struct database *head) {
    char firstname[50];
    char lastname[50];
    double average;

    if (scanf("%49s %49s %lf", firstname, lastname, &average) != 3) {
        printf("invalid input\n");
        return;
    }

    struct student *temp = head->first;
    while (temp != NULL) {
        if (strcmp(temp->firstname, firstname) == 0
        &&  strcmp(temp->lastname, lastname) == 0) {
            printf("TTT\n");
            temp->average = average;
        }
        temp = temp->next;
    }
}

void vypis(struct database *head) {
    struct student *temp = head->first;
    while (temp != NULL) {
        printf("lastname=%s, firstname=%s, year=%d, average=%.2lf\n",
               temp->firstname, temp->lastname, temp->year, temp->average);
        temp = temp->next;
    }
    printf("\n");
}

int main() {
    char prikaz[20];
    struct database *head = create_head();
    while (scanf("%19s", prikaz) == 1) {
        if (strcmp(prikaz, "vloz") == 0)
            vloz(head);
        else
        if (strcmp(prikaz, "vypis") == 0)
            vypis(head);
        else
        if (strcmp(prikaz, "zmen") == 0)
            zmen(head);
    }
    return 0;
}