1

The error is referencing the following line of code:

tenant[i].name = get_string("Enter the residents name: ");

and has an arrow pointing at the period . between tenant[i] and name. I am not sure what I am missing.

typedef struct {
    string name;
    int apt;
} tenant;

int n;

int numres(void);

string nameres(int numres);

int apt(int numofres);

int main(void) {
    int numres(void);

    tenant tenants[n];

    string nameres(int n);

    int apt(int n);

    for (int m = 0; m < n; m++) {
        printf("Resident %s resides in apt# %i\n",
               tenants[m].name, tenants[m].apt);
    }
    return 0;
}

//this function prompts the user for the number of residents
int numres(void) {
    do {
        n = get_int("Enter the number of residents: ");
    } while (isalpha(n) != 0 || isspace(n) != 0);
    return n;
}

// this function prompts the user for the residents names.
string nameres(int numres) {
    int i = 0;
    do {
        tenant[i].name = get_string("Enter the residents name: ");
        return tenant[i].name;
        i++;
    } while (i < numres);
}

// this function prompts the user for the residents apt number
int apt(int numofres) {
    for (int i = 0; i < numofres; i++) {
        tenant[i].apt = get_int("Enter residents apt number: ");
        return tenant[i].apt;
    }
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Dansah
  • 11
  • 2
  • 1
    tenant is a type. tenants is a variable. You mistyped. – Avi Berger Sep 20 '22 at 00:46
  • 1
    Once you fix the typo you'll have a bunch of other things to fix. `tenants` is a local variable in the `main` function, so where you try to use it in other functions it will not exist. `int numres(void);` is a forward declaration of a function, not a function call. To call the function you'd use `numres();` – Retired Ninja Sep 20 '22 at 00:57
  • That global `int n` is surely a mistake. It doesn't belong there. – tadman Sep 20 '22 at 01:04
  • Why is there a `return` that always fires inside the "loop" of your `nameres()` function? What is the purpose of that? This code doesn't make any sense. – tadman Sep 20 '22 at 01:05
  • This is the darker side of "refactoring" code when the basic implementation hasn't been shown to work to begin with... – Fe2O3 Sep 20 '22 at 02:33
  • There is no `string` type in C. Do you use some `cs50` header you did not show us or do you use C++? – Gerhardh Sep 20 '22 at 07:30

1 Answers1

0

There are multiple problems in the code:

  • the string type is not a standard C type, it is defined in <cs50.h> as a typedef for char *, which can be quite confusing. Make sure you include <cs50.h> and <stdio.h>.

  • in the main function, you define tenant tenants[n];, an array with a length specified by a variable that has a value of 0: this has undefined behavior, and the array cannot be used for anything.

  • in the main function, you declare functions int numres(void);, string nameres(int n); and int apt(int n);. Such declarations should be made at the file scope, and indeed are done so already. You probably meant to call the functions instead, so you should write:

    int main(void) {
        numres();
    
        tenant tenants[n];
    
        nameres(n);
        apt(n);
    
        for (int m = 0; m < n; m++) {
            printf("Resident %s resides in apt# %i\n",
                   tenants[m].name, tenants[m].apt);
        }
        return 0;
    }
    

    But passing the value of n as a global variable is cumbersome and confusing. numres() should return the value and n should be a local variable.

  • in numres, it does not make sense to test isalpha(n) != 0 || isspace(n) != 0 because n is a number, not the value of a byte read from the input stream. The function get_int already checks for valid input and returns a converted number, you should just check that the number is positive: n > 0.

  • nameres should be defined as a void function and use a for loop for the case where n has the value 0.

  • in nameres and apt should receive tenants as an argument as this array is defined locally in main. The code should use tenants instead of tenant, which is a type name. This is the reason for your compilation issue. Using a _t suffix for the types is recommended to avoid such problems.

  • in nameres and apt should should prompt for the name and apartment numbers of all residents, remove the return statements.

  • using while or for loops instead of do / while loops allows for more concise code with explicit tests closer to the generating fact.

Here is a modified version:

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

typedef struct tenant_t {
    string name;
    int apt;
} tenant_t;

int numres(void);
void nameres(tenant_t tenants[], int numres);
void apt(tenant_t tenants[], int numres);

int main() {
    int n = numres();

    tenant_t tenants[n];

    nameres(tenants, n);
    apt(tenants, n);

    for (int i = 0; i < n; i++) {
        printf("Resident %s resides in apt# %i\n",
               tenants[i].name, tenants[i].apt);
    }
    return 0;
}

// this function prompts the user for the number of residents
// it returns the number which must be strictly positive
int numres(void) {
    for (;;) {
        int n = get_int("Enter the number of residents: ");
        if (n > 0)
            return n;
    }
}

// this function prompts the user for the residents names.
void nameres(tenant_t tenants[], int numres) {
    for (int i = 0; i < numres; i++) {
        tenants[i].name = get_string("Enter the residents name: ");
    }
}

// this function prompts the user for the residents apt number
void apt(tenant_t tenants[], int numres) {
    for (int i = 0; i < numres; i++) {
        tenants[i].apt = get_int("Enter residents apt number: ");
    }
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189