这里我做错了什么?无论我做什么,函数askSubscriptionQuestions都不会存储4个浮点数的值

gzszwxb4  于 2023-01-08  发布在  其他
关注(0)|答案(2)|浏览(123)

这是一个计算所有月订阅总额的程序。但问题是netflixBill,disneyBill等的值在函数调用时为0,所以总额只是struct元素。我已经尝试了所有我知道的方法,但我不明白为什么它不起作用。enter image description here

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

struct Subscription {
  char name[100];
  float price;
};


int check_login(char *, char *);
void askSubscriptionQuestions(bool *, bool *, bool *, bool *);
struct Subscription ask_subscription();
float total_price(struct Subscription subscriptions[], int num_subscriptions, float netflixBill, float disneyBill, float hboBill, float spotifyBill);

struct Subscription ask_subscription(void) {
  struct Subscription subscription;
  printf("What is the name of the subscription? ");
  scanf("%s", subscription.name);
  printf("How much do you pay every month for it? ");
  scanf("%f", &subscription.price);
  return subscription;
}

int main()
{
  float netflixBill = 0.0f, disneyBill = 0.0f, hboBill = 0.0f, spotifyBill = 0.0f;
  char id[20];
  char password[20];
  bool hasPassed;
  bool hasNetflix;
  bool hasDisneyPlus;
  bool hasHBO;
  bool hasSpotify;
  char response;
  struct Subscription subscriptions[100];
  int num_subscriptions = 0;
  while (1) {
    printf("Enter your ID: ");
    scanf("%s", id);

    printf("Enter your password: ");
    scanf("%s", password);

    if (check_login(id, password)) {
      printf("Access granted.\n");
      hasPassed = true;
      break;
    } else {
      hasPassed = false;
      printf("Access denied.\n");
    }
  }


  printf("Do you have any monthly subscriptions? (y/n) ");
  char c;

  while (c != 'y' && c != 'Y' && c != 'n' && c != 'N') {
    scanf("%s", &c);
    if (c != 'y' && c != 'Y' && c != 'n' && c != 'N'){
      printf("Invalid input. Please enter 'y' or 'n': ");
    }
  }
printf("%f %f %f %f", netflixBill, disneyBill, hboBill, spotifyBill);
  if (c == 'y' || c == 'Y') {
    askSubscriptionQuestions(&hasNetflix, &hasDisneyPlus, &hasHBO, &hasSpotify);
  } else if (c == 'n' || c == 'N') {
    printf("OK, thank you for your answer.\n");
  }printf("%f %f %f %f", netflixBill, disneyBill, hboBill, spotifyBill);

  printf("Do you have any other monthly subscriptions (Y/N)? ex: YT Premium, iCloud, etc.\n");
  scanf("%s", &response);

  while (response == 'Y' || response == 'y') {
    subscriptions[num_subscriptions] = ask_subscription();
    num_subscriptions++;

    printf("Do you have any other monthly subscriptions (Y/N)? ");
    scanf("%s", &response);
  }

  if (num_subscriptions > 0) {
    printf("Your subscriptions are:\n");
    for (int i = 0; i < num_subscriptions; i++) {
      printf("- %s: $%.2f\n", subscriptions[i].name, subscriptions[i].price);
    }
  } else {
    printf("You do not have any other monthly subscriptions.\n");
  }

  float total = total_price(subscriptions, num_subscriptions, netflixBill, disneyBill, hboBill, spotifyBill);
    printf("The total cost of all your subscriptions is $%.2f\n", total);
  return 0;
}

int check_login(char *id, char *password) {
  if (strcmp(id, "admin") == 0 && strcmp(password, "pass123") == 0) {
    return 1;
  } else {
    return 0;
  }
}

void askSubscriptionQuestions(bool *hasNetflix, bool *hasDisneyPlus, bool *hasHBO, bool *hasSpotify) {
  char c;
  int netflixPlan, spotifyPlan;
  float netflixBill = 0.0f, disneyBill = 0.0f, hboBill = 0.0f, spotifyBill = 0.0f;
  printf("Do you have a subscription to Netflix? (y/n) ");
  scanf("%s", &c);
  if (c == 'y' || c == 'Y') {
    *hasNetflix = true;
    printf("Which monthly plan do you have? Here is a list: \n");
    printf("\t 1 for Minimum = 7.99$/month\n");
    printf("\t 2 for Standard = 9.99$/month\n");
    printf("\t 3 for Premium = 11.99/month\n");
    scanf("%d", &netflixPlan);
    if(netflixPlan == 1){
        netflixBill = 7.99;
    }
        else if(netflixPlan == 2){
            netflixBill = 9.99;
        }
            else
                netflixBill = 11.99;
        } else {
    *hasNetflix = false;
    printf("You don't have a Netflix subscription. \n");
  }

  printf("Do you have a subscription to Disney+? (y/n)\n ");
  scanf("%s", &c);
  if (c == 'y' || c == 'Y') {
    *hasDisneyPlus = true;
    disneyBill = 5.99;
    printf("The subscription for Disney+ is 5.99$/month.\n");
  } else {
    *hasDisneyPlus = false;
    printf("You don't have a Disney+ subscription. \n");
  }

  printf("Do you have a subscription to HBO? (y/n)\n ");
  scanf("%s", &c);
  if (c == 'y' || c == 'Y') {
    *hasHBO = true;
    hboBill = 4.99;
    printf("The subscription for HBO is 4.99$/month.\n");
  } else {
    *hasHBO = false;
    *hasHBO = false;
    printf("You don't have a HBO subscription. \n");
  }

  printf("Do you have a subscription to Spotify? (y/n) ");
  scanf("%s", &c);
  if (c == 'y' || c == 'Y') {
    *hasSpotify = true;
    printf("Which monthly plan do you have? Here is a list: \n");
    printf("\t 1 for Premium = 4.99$/month\n");
    printf("\t 2 for Premium for students = 2.49$/month\n");
    scanf("%d", &spotifyPlan);
    if(spotifyPlan == 1)
        spotifyBill = 4.99;
        else
            spotifyBill = 2.49;
  } else {
     printf("You don't have a Spotify subscription. \n");
    *hasSpotify = false;
  }
}

float total_price(struct Subscription subscriptions[], int num_subscriptions, float netflixBill, float disneyBill, float hboBill, float spotifyBill) {
  float total = netflixBill + disneyBill + hboBill + spotifyBill;
  for (int i = 0; i < num_subscriptions; i++) {
    total += subscriptions[i].price;
  }
  return total;
}

我试过使用指针(idk如果我做得对的话).试过使用chatgpt但是它也不知道问题是什么.

lvjbypge

lvjbypge1#

未初始化的变量:

char c;
while (c != 'y' && c != 'Y' && c != 'n' && c != 'N')

此循环调用未定义的行为,因为c从未初始化。

格式说明符不正确:

scanf("%s", &c);

scanf的调用也会调用Undefined Behaviour,因为c已声明为char,并且%s说明符用于字符串。
我数了7个你犯同样错误的例子。
一旦抽象状态机到达未定义状态,就不能进一步假设程序的执行是否继续。

变量范围:

main中定义的变量仅对main是局部的。您在askSubcriptionQuestions中声明了spotifyBill ...的另一个示例,这些变量仅对askSubcriptionQuestions是局部的。它们在main中不可见,并且在main中声明的变量在其他函数中不可见。

  • 标识符只能在其作用域内可见,从其声明开始。
  • 对象有一个生命周期,超过这个生命周期就不能被访问。
  • 在对象生存期之外引用对象具有未定义的行为。
  • 除非是VLA或临时对象,否则自动变量的生存期与其定义块的执行相对应

如果你想使用main中声明的相同变量,你必须将它们传递给其他函数by reference,这样,对这些变量所做的更改将是永久性的。

yebdmbv4

yebdmbv42#

您的问题与变量的作用域有关。
实际上,你在函数 askSubscriptionQuestions 中使用了局部变量来赋值,但是当你终止这个函数时,所有的局部变量都丢失了。不要因为你命名它们的方式和main中声明的变量一样而感到困惑。这并不重要,重要的是变量的作用域。
一旦你在main中声明了你的 netflixBill 变量,你需要通过引用传递它,也就是说,传递变量的地址而不是值。你可以使用“&"来完成这一操作。这样,如果你在函数内部正确地修改了这个地址所指向的值,当它完成时,你不会丢失变量的值。
您需要进行以下几项更改:

  • 重写函数,使函数头包含以下变量(将参数定义为地址):

无效提问订阅问题(...,netflixBill, 迪斯尼Bill,hboBill, spotify Bill)

  • 将函数调用为(发送地址而不是值):

询问订阅问题(...,&netflixBill,&迪斯尼Bill,&hboBill,& spotify Bill)

  • 在你的函数中,每次你想改变这些变量的值时,你需要调用地址所指向的“值”,所以,改变就是每次你在这个函数中调用这些变量**时,总是在前面加上一个“*”,例如:
  • 网飞账单= 7.99;
  • 删除您正在对 netflixBill 变量和函数内类似变量执行的局部声明。

我强烈建议你学习和理解通过引用和通过值传递变量到函数的概念,这是C语言中必不可少的编码。

相关问题