Example #1
0
/* Return the balance of the user or -1 if the user does not exist.
*/
double user_balance(Group *group, const char *user_name) {
    
    User * prev_user = find_prev_user(group, user_name);
    if (prev_user == NULL) { 
        return (double)(-1);
    }
    
    
    if (prev_user == group->users) {
        
        // user could be first or second since previous is first
        if (strcmp(user_name, prev_user->name) == 0) {
            // this is the special case of first user
            
            //LEO MOD:
            //printf("Balance is %f\n", prev_user->balance);
            //return 0;
            return prev_user->balance;
        }
    }
    //LEO MOD:
    //printf("Balance is %f\n", prev_user->next->balance);
    //return 0;
    return prev_user->next->balance;
}
Example #2
0
/* Add a new user with the specified user name to the specified group. Return zero
* on success and -1 if the group already has a user with that name.
* (allocate and initialize a User data structure and insert it into the
* appropriate group list)
*/
int add_user(Group *group, const char *user_name) {
    User *this_user = find_prev_user(group, user_name);
    if (this_user != NULL) {
        return -1;
    }
    // ok to add a user to this group by this name
    // since users are stored by balance order and the new user has 0 balance
    // he goes first
    User *newuser;
    if ((newuser = malloc(sizeof(User))) == NULL) {
        perror("Error allocating space for new User");
        exit(1);
    }
    // set the fields of the new user node
    // first allocate space for the name
    size_t name_len = strlen(user_name);
    if ((newuser->name = malloc(name_len + 1)) == NULL) {
        perror("Error allocating space for new User name");
        exit(1);
    }
    strncpy(newuser->name, user_name, name_len + 1);
    newuser->balance = 0.0;

    // insert this user at the front of the list
    newuser->next = group->users;
    group->users = newuser;
    return 0;
}
Example #3
0
/* Print to standard output the balance of the specified user. Return 0
 * on success, or -1 if the user with the given name is not in the group.
 */
int user_balance(Group *group, const char *user_name) {
    User *prev_user = find_prev_user(group, user_name);
    if (prev_user == NULL) {
        return -1;
    } else if (strcmp(prev_user->name, user_name) == 0) {
        printf("BALANCE\n-------\n");
        printf("%c%.2f (%s)\n", CURRENCY, prev_user->balance, prev_user->name);
        return 0;
    } else {
        printf("BALANCE\n-------\n");
        printf("%c%.2f (%s)\n", CURRENCY, prev_user->next->balance, prev_user->next->name);
        return 0;
    }
}
Example #4
0
/* Remove the user with matching user and group name and
 * remove all her transactions from the transaction list.
 * Return 0 on success, and -1 if no matching user exists.
 * Remember to free memory no longer needed.
 * (Wait on implementing the removal of the user's transactions until you
 * get to Part III below, when you will implement transactions.)
 */
int remove_user(Group *group, const char *user_name) {
    /* Gets the previous user before the user to be deleted if the to be deleted
     * user is not a head. If the to be deleted user is a head, the to be deleted
     * is returned. If the user doesn't exist in the group, NULL is returned.
     */
    User *prev_user = find_prev_user(group, user_name);

    /* If the user returned is not NULL, this means that user exists in the group,
     * therefore we check if the returned user is a head or the previous user.
     *      1) If it is a previous user, we set the previous user next pointer to
     *         the next next user and free space for the deleted user.
     */
    if (prev_user != NULL) {
        if (strcmp(prev_user->name, user_name) == 0) {
            group->users = prev_user->next;
            remove_xct(group, user_name);
            free_dp(prev_user->name);
            free_dp(prev_user);
            return 0;

        /*      2) If it is a head node, we reset the head to the next user and free
         *         up space for the deleted node. Free space for the user name 
         *         and the user, also points the user to NULL to avoid dangling 
         *         pointers.
         */
        } else if (strcmp(prev_user->next->name, user_name) == 0) {
            User *temp = prev_user->next;
            prev_user->next = prev_user->next->next;
            remove_xct(group, user_name);
            free_dp(temp->name);
            free_dp(temp);
        }

        // Return 0 if we the deletion is successful.
        return 0;

    /* If the user returned is NULL, that means the user name doesn't exist, no
     * users are deleted, and -1 is returned.
     */
    } else {
        return -1;
    }
}
Example #5
0
/* Add the transaction represented by user_name and amount to the appropriate 
* transaction list, and update the balances of the corresponding user and group. 
* Note that updating a user's balance might require the user to be moved to a
* different position in the list to keep the list in sorted order. Returns 0 on
* success, and -1 if the specified user does not exist.
*/
int add_xct(Group *group, const char *user_name, double amount) {
    User *this_user;
    User *prev = find_prev_user(group, user_name);
    if (prev == NULL) {
        return -1;
    }
    // but find_prev_user gets the PREVIOUS user, so correct
    if (prev == group->users) {
        // user could be first or second since previous is first
        if (strcmp(user_name, prev->name) == 0) {
            // this is the special case of first user
            this_user = prev;
        } else {
            this_user = prev->next;
        }
    } else {
        this_user = prev->next;
    }

    Xct *newxct;
    if ((newxct = malloc(sizeof(Xct))) == NULL) {
        perror("Error allocating space for new Xct");
        exit(1);
    }
    // set the fields of the new transaction node
    // first allocate space for the name
    size_t needed_space = strlen(user_name) + 1;
    if ((newxct->name = malloc(needed_space)) == NULL) {
         perror("Error allocating space for new xct name");
         exit(1);
    }
    strncpy(newxct->name, user_name, needed_space);
    newxct->amount = amount;

    // insert this xct  at the front of the list
    newxct->next = group->xcts;
    group->xcts = newxct;

    // first readjust the balance
    this_user->balance = this_user->balance + amount;

    // since we are only ever increasing this user's balance they can only
    // go further towards the end of the linked list
    //   So keep shifting if the following user has a smaller balance

    while (this_user->next != NULL &&
                  this_user->balance > this_user->next->balance ) {
        // he remains as this user but the user next gets shifted
        // to be behind him
        if (prev == this_user) {
            User *shift = this_user->next;
            this_user->next = shift->next;
            prev = shift;
            prev->next = this_user;
            group->users = prev;
        } else { // ordinary case in the middle
            User *shift = this_user->next;
            prev->next = shift;
            this_user->next = shift->next;
            shift->next = this_user;
        }
    }
	return 0;
}
Example #6
0
/* Add the transaction represented by user_name and amount to the appropriate
 * transaction list, and update the balances of the corresponding user and group.
 * Note that updating a user's balance might require the user to be moved to a
 * different position in the list to keep the list in sorted order. Returns 0 on
 * success, and -1 if the specified user does not exist.
 */
int add_xct(Group *group, const char *user_name, double amount) {
    /* Allocate space for the new xct that is to be added to the list of
     * xcts.
     */
    Xct *new_xct = (Xct*) malloc (sizeof(Xct));

    /* Checks if malloc failed, if malloc failed, a error message is printed to
     * standard output and exit code of 256.
     */
    if (new_xct == NULL) {
        print_exit("ERROR: Malloc failed", 256);

    /* If malloc didn't fail, the user name and the amount is assigned to the new
     * xct and the next pointer is set to NULL temporarily.
     */
    } else {
        int size_to_malloc = (strlen(user_name)+1)*sizeof(char);
        new_xct->name = (char*) malloc (size_to_malloc);

        /* Checks if the current malloc failed, if it failed a message is printed
         * to standard output and exit code of 256 is set.
         */
        if (new_xct->name == NULL) {
            print_exit("ERROR: Malloc failed", 256);
        }
        strncpy(new_xct->name, user_name, size_to_malloc);
        new_xct->name[size_to_malloc] = '\0';
        new_xct->amount = amount;
        new_xct->next = NULL;
    }

    /* Finds the previous user to the user that added a xct in order to change
     * the user's balance and re-organize the list.
     */
    User *prev_user = find_prev_user(group, user_name);

    /* If no user was found with the same user name in the list of users, -1 is
     * returned.
     */
    if (prev_user == NULL) {
        free_dp(new_xct->name);
        free_dp(new_xct);
        return -1;

    /* Checks if the user returned is the head of the list of users, if it is, 
     * the head is changed so that the user can be moved to its correct location.
     */
    } else if (strcmp(prev_user->name, user_name) == 0) {
        push_xct(group, new_xct);
        prev_user->balance += amount;
        sort_user(group, prev_user, user_name);
        return 0;

    /* Checks if the user returned is in the middle of the list of users, the 
     * user is remvoed from its current position and placed in the correct
     * position in the users of list.
     */
    } else {
        push_xct(group, new_xct);
        prev_user->next->balance += amount;
        sort_user(group, prev_user, user_name);
        return 0;
    }
}
Example #7
0
/* Add a new user with the specified user name to the specified group. Return zero
 * on success and -1 if the group already has a user with that name.
 * (allocate and initialize a User data structure and insert it into the
 * appropriate group list)
 */
int add_user(Group *group, const char *user_name) {
    /* Allocates space in memory for the user, and checks if malloc has been
     * completed successfully.
     */
    User *new_user = (User*) malloc (sizeof(User));

    /* If malloc is not completed succesfully, an error message will be printed
     * out to standard output and program will exit with 256 exit code
     */
    if (new_user == NULL) {
        print_exit("ERROR: Malloc failed", 256);

    /* If malloc has been completed successfully, the user name is set to user_name
     * and set initial balance to 0
     */
    } else {
        int size_to_malloc = (strlen(user_name)+1)*sizeof(char);
        new_user->name = (char*) malloc (size_to_malloc);

        /* Checks if malloc is completed succesfully, if it is not completed
         * successfully, and error message will be printed out the screen and exit
         * code of 256.
         */
        if (new_user->name == NULL) {
            print_exit("ERROR: Malloc failed", 256);
        }

        /* Copies the user_name given to the user name got the newly created
         * user.
         */
        strncpy(new_user->name, user_name, size_to_malloc);
        new_user->name[size_to_malloc] = '\0';

        /* Sets all other values to either 0.0 if it is double, or NULL if it is
         * a pointer to another linked list.
         */
        new_user->balance = 0.0;
        new_user->next = NULL;
    }

    // Returns the user if the user already exists in the group.
    User *prev_user = find_prev_user(group, user_name);

    /* If prev_user is NULL, meaning no user in the group exists with the same
     * name. We can add the new user in this case to the specified group.
     */
    if (prev_user == NULL) {
        prev_user = new_user;
        User *tmp = group->users;
        group->users = prev_user;
        group->users->next = tmp;
        return 0;

    /* If prev_user is not NULL, this means that a user with the same name already
     * exists, so we don't add the new user and just return -1. Free space for 
     * the user name and the user, also points the user to NULL to avoid dangling 
     * pointers
     */
    } else {
        free_dp(new_user->name);
        free_dp(new_user);
        return -1;
    }
}