strcmp не вернет 0 при сравнении строки с элементом данных связанного списка - PullRequest
0 голосов
/ 04 мая 2019

У меня возникли проблемы с программой со связанным списком, в которой 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 ]

2 голосов
/ 05 мая 2019

Вы поменяли имя и фамилию, поэтому сравнение не работает.

Во 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

0 голосов
/ 05 мая 2019

В опубликованном коде есть некоторые проблемы, но ничего не объясняет ваши наблюдения.

Проблема должна быть в другом месте, в функциях, которые вы написали для анализа файла и построения списка. Разместите полный код в работающей программе, которая демонстрирует неожиданное поведение.

Вот некоторые проблемы в вашем коде:

  • Вы всегда должны проверять возвращаемое значение 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(); } бесполезен: если список не пуст, вы выделяете новое дерево для новой локальной переменной, которая сразу выходит из области видимости.

  • Вы неправильно сравниваете имена в функции сканирования.

  • Пожалуйста, используйте английские имена для своих функций, je ne comprends pas le slovaque.

Вот модифицированная версия:

#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;
}
...