Проблема с царапинами cs50 не работает. может кто-нибудь помочь, плз?

Я решаю задачи cs50 из набора задач 2, и моя функция «точка» неправильно добавляет очки. Функция продолжает игнорировать все операторы if и else if, даже если есть символы, соответствующие этому оператору if.

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

int score1 = 0;
int score2 = 0;
int point(string ply);
void compare(int pl1, int pl2);

int main(void)
{
    string ply1 = get_string("Player 1: ");
    string ply2 = get_string("Player 2: ");

    score1 = point(ply1);
    score2 = point(ply2);
    compare(score1, score2);
}



//calculate point
int point(string ply)
{
    int score = 0;

    for(int i = 0; i < strlen(ply); i++)
    {
        if (ply[i] == ('a'|'e'|'i'|'l'|'n'|'o'|'r'|'s'|'t'|'u'))
        {
            score += 1;
            printf("yes\n");
        }
        else if (ply[i] == ('d'|'g'))
        {
            score += 2;
        }
        else if (ply[i] == ('b'|'c'|'m'|'p'))
        {
            score += 3;
        }
        else if (ply[i] == ('f'|'h'|'v'|'w'|'y'))
        {
            score += 4;
        }
        else if (ply[i] == 'k')
        {
            score +=5;
        }
        else if (ply[i] == ('j'|'x'))
        {
            score += 8;
        }
        else
        (
            score += 10
        );
    }
    return score;
}

//compare score
void compare(int pl1, int pl2)
{
    if (pl1 < pl2)
    {
        printf("Player 2 won!\n");
    }
    else if (pl1 > pl2)
    {
        printf("player 1 won!\n");
    }
    else
    {
        printf("tie\n");
    }
}

Я запускаю это в отладчике cs50, и когда дело доходит до функции if, она ничего не добавляет к оценке, а просто пропускает.

Что вам расскажет курс CS50 о передаче аргументов функциям? Он должен был научить вас, что аргументы передаются по значению. Это означает, что значение в вызове копируется в переменную локального аргумента функции. Любые изменения, которые вы вносите в переменные локальных аргументов функции, будут потеряны при возврате функции.

Some programmer dude 12.06.2024 09:58

И ply[i] == ('a'|'e'|'i'|'l'|'n'|'o'|'r'|'s'|'t'|'u') не делает того, что вы думаете. Он вычисляет ('a'|'e'|'i'|'l'|'n'|'o'|'r'|'s'|'t'|'u') с использованием побитового ИЛИ, создавая ненулевое значение. Затем вы сравниваете это ненулевое значение с ply[i]. Если вы хотите сравнить несколько значений, вам необходимо выполнить несколько сравнений. Например, ply[i] == 'a' || ply[i] == 'e' и т. д. Также обратите внимание на использование логического оператора ИЛИ ||.

Some programmer dude 12.06.2024 09:59

как мне написать это так, чтобы ply[i] сравнивал себя с этими буквами индивидуально и возвращал true, когда оно правильное. я пытался использовать || но это не позволяет мне сделать это

Lanvo 12.06.2024 10:03

«но это не позволяет мне это сделать», значит, вы сделали это неправильно. То, как SomeProgrammerDude показал это в комментарии выше вашего, правильно. Если это не работает для вас, вам нужно обновить свой вопрос. Добавьте новую версию внизу, не удаляйте исходный код.

Gerhardh 12.06.2024 10:29

Проблема в том, что вы просто вводите случайные данные и надеетесь, что именно так работает язык программирования. Но программирование так не работает — здесь нет метода «рискнуть», метода проб и ошибок. Вы либо знаете, как что-то работает, либо нет. Если нет, вы ищете это в книге или другом источнике обучения.

Lundin 12.06.2024 10:45

Кроме того: ошибка расчета: пустое значение равно 0. point() дает ему оценку 10.

chux - Reinstate Monica 12.06.2024 17:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Условия, которые у вас есть, не делают того, что вы думаете.

Во-первых, напоминаем, что литералы char, такие как 'a', на самом деле являются просто причудливым способом записи чисел — они интерпретируются как их значения ASCII. | — это оператор bitwsie или . Итак, когда у вас есть оператор типа ply[i] == ('a'|'e'|'i'|'l'|'n'|'o'|'r'|'s'|'t'|'u'), вычисляется правая часть равенства (она равна 127), а затем ply[i] сравнивается с ней.

Правильный синтаксический способ записи условия, которое вы намеревались написать, — это серия логических или условий:

if (ply[i] == 'a' ||
    ply[i] == 'e' ||
    ply[i] == 'i' || 
    ply[i] == 'l' ||
    ply[i] == 'n' ||
    ply[i] == 'o' ||
    ply[i] == 'r' ||
    ply[i] == 's' ||
    ply[i] == 't' ||
    ply[i] == 'u') {
score += 1;
}
// else if etc...

Но это очень громоздко. Более аккуратное решение могло бы заключаться в реализации хэш-карты бедняка.
Каждый персонаж от 'a' до 'z' приносит определенное количество очков. А поскольку литералы char — это просто причудливые числа, если из каждого 'a' вычесть char, вы получите числа от 0 до 25, которые можно использовать в качестве индексов массива.
Вы можете создать массив значений точек:

const int POINTS[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};
int points (char* str) {
    int score = 0;
    for (int i = 0; i < strlen(str); ++i) {
        score += POINTS[str[i] - 'a'];
    }
    return score;
}

Строго говоря, не стоит учить новичков выполнять арифметические действия с символьными константами, поскольку, строго говоря, нет никакой гарантии, что a и z соседствуют (утомительный старый аргумент EBCDIC). Вместо этого я бы пожертвовал несколькими сотнями байт ПЗУ и сделал что-то вроде const uint8_t POINTS[256] = { ['a']=1, ['b']=3, ...};... score += POINTS[str[i]];. Желающие могут добавить версию в верхнем регистре внутри той же таблицы. В качестве бонуса это также дает ноль баллов за все небуквы.

Lundin 12.06.2024 11:02

Если суммируемая плитка представляет собой blank, POINTS[str[i] - 'a'] будет проблемой.

chux - Reinstate Monica 12.06.2024 17:54

@Lundin педантичный: score += POINTS[str[i]]; будет проблемой, когда char в str[i] будет отрицательным.

chux - Reinstate Monica 12.06.2024 17:56

@Mureinik хорошо объясняет проблему ОП.

Альтернативные подведения итогов, как прокомментировал @Lundin

#include <ctype.h>

int point_alternative1(string ply) {
  static const unsigned char points[] = { ['A']=1, ['B']=3, /* 23 more */ ['Z']=10};

  int score = 0;
  for(size_t i = 0; ply[i]; i++) {
    unsigned char character = str[i];
    character = toupper(character);
    if (character < sizeof points) {
      score += points[character];
    }
  }
  return score;
}

// OR

#include <limits.h>

int point_alternative2(string ply) {
  static const unsigned char points[UCHAR_MAX + 1] = { //
      ['A']=1, ['B']=3, /* 23 more */ ['Z']=10, //
      ['a']=1, ['b']=3, /* 23 more */ ['z']=10 };

  int score = 0;
  for(size_t i = 0; ply[i]; i++) {
    score += points[(unsigned char) ply[i]];
  }
  return score;
}

// OR

#include <limits.h>

int point_alternative3(const char *s) {
  static const unsigned char points[UCHAR_MAX + 1] = { //
      ['A']=1, ['B']=3, /* 23 more */ ['Z']=10, //
      ['a']=1, ['b']=3, /* 23 more */ ['z']=10 };
  const unsigned char *us = (const unsigned char *) s;

  int score = 0;
  while (*us) {
    score += points[*us++];
  }
  return score;
}

Другие вопросы по теме