-1

I'm a little new to C programming but have some experience. To test my skills, I was trying to build a Bank management program that allows you to create your account, make deposits/withdrawals, etc. The code that I have so far is:

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

char username[20];
char password[20];

void create_account(char* usrname, char* passwd) {
    printf("==================================CREATE BANK ACCOUNT==================================\n");
    while(1) {
        printf("Enter a username that is less than 20 characters: ");
        scanf("%s", usrname);

        if (strlen(usrname) <= 20)
            break;

        printf("That is not less than 20 characters, try again...\n");
    }

    while(1) {
        printf("Enter a password that is less than 20 characters: ");
        scanf("%s", passwd);

        if (strlen(passwd) <= 20) {
            break;
        }
    }

    printf("Thank you, please sign in now...\n");
    sleep(2);
}

int main(void) {
    create_account(username, password);
    printf("\n%s", username);
    printf("\n%s", password);
    return 0;
}

I am aware that I have no parameters when I'm calling the function in main but that's because I don't know what parameters to pass through in the function declaration/initialization so for now, I keep it blank. My question is how do I pass 2 arrays into a function, ask the user to create a username and password, store it in their respective arrays and return both arrays to the program? I know it has to do something with pointers but don't know what to do. I know there is a way to do this with structures too but I don't know anything about that, unions, typedefs, or anything advanced. I really am a novice so please, if the answer is simple, don't get mad at me. Thanks in advance!

Edit: I've read through everyone's comments and answers and made the necessary changes to the code except for the one where someone mentioned using fgets instead of scanf. I don't really understand what to do so I just left it, despite the fact that he said scanf is just as dangerous as gets. I think I got everything but if someone has something else, please let me know. Thank you everyone.

Matthew Schell
  • 599
  • 1
  • 6
  • 19
  • You are also calling `create_account` from within itself in recursive fashion. Is there a reason to do that? – unxnut Oct 24 '20 at 01:17
  • I do that for error handling. Instead of exiting the program if the user doesn't follow directions, i give them another try. Normally, I'm pretty sure that there would be an error if one of the strings are greater than 20 since i gave that specific size – Matthew Schell Oct 24 '20 at 03:31
  • `char* username[20];` creates a global array of *20 pointers to* `char` -- not what you want. Get rid of the `'*'`... – David C. Rankin Oct 24 '20 at 03:56
  • Also use `fgets()` instead of `scanf()` to read the strings -- and then remove the trailing `'\n'` with `usrname[strcspn (usrname, "\n")] = 0;` overwriting the `'\n'` with `'\0'` (which is simply ASCII `0`, so `'\0'` and `0` are equivalent). Also you must include a *field-width* modifier when using `scanf()` to read a string (e.g. `"%19s"`) otherwise `scanf()` is just as dangerous as `gets()`, see [Why gets() is so dangerous it should never be used!](https://stackoverflow.com/q/1694036/3422102) – David C. Rankin Oct 24 '20 at 04:11
  • Don't call a function to "give another try". Use a loop. What happens is when the 2nd try succeeds, prints "Thanks" and the function returns, it returns to the 2nd call within itself, and will print "Thank you ..." again. A function calling itself is called recursion and is used in specific instances when recursion is required...and this isn't it. – Mark Tolonen Oct 24 '20 at 04:14
  • Additionally, you cannot use any user-input function correctly without ***checking the return*** to validate that the input and any conversion succeeded or failed. Otherwise you invite *Undefined Behavior* by blindly using unvalidated input. If you do use `scanf()` then `if (scanf ("%19s", usrname) != 1) { /* handle error */ }` – David C. Rankin Oct 24 '20 at 04:17
  • Lastly, `strlen(usrname)` can NEVER be more than `19` -- otherwise you have invoked *Undefined Behavior* and the defined operation of your code ceases. Your code may appear to work correctly or SegFault or anything in between. The behavior is simply *Undefined*. – David C. Rankin Oct 24 '20 at 04:27

1 Answers1

1

What you can do is create 2 global arrays :

char username[20];
char password[20];

Note that the variables aren't pointers.

Then in the argument passed to the function create_account, you receive pointers that point to the addresses of the two arrays created :

void create_account(char* usrname, char* passwd) {

      /* code... */
}

Remember, the asterisk means "the contents of address...".

To validate the the user's input, I prefer using an infinte loop. The program will break out of the loop once the user enters a valid username (the same can be done for the password) :

while(1) {
    printf("Enter a username that is less than 20 characters: ");
    scanf("%s", usrname);
    
    if (strlen(usrname) <= 20)
        break;

    printf("That is not less than 20 characters, try again...\n");
}

Finally, in the main function when calling create_account, you pass the array variables :

int main(void) {
    create_account(username, password);
    return 0;
}

Just before the return statement you can print out the entered username and password :

printf("\n%s", username);
printf("\n%s", password);
  • 2
    Good eye -- but, if they are global -- there is no need to pass the arrays a parameters. Discourage the use of globals and encourage declaring the arrays within the scope needed (`main()` here) and passing as parameters to any functions that require them. – David C. Rankin Oct 24 '20 at 03:58
  • Sure and in the paragraph about asterisk means "the contents of the address...", generally true, but that isn't why the parameters are pointers. The parameters are pointers due to array-pointer conversion which occurs when an array is accessed, the array is converted to a pointer to its first element. That's why the parameters are pointers, [C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)](http://port70.net/~nsz/c/c11/n1570.html#6.3.2.1p3) (**note:** the 4 exceptions - 3 under C17 - `_Alignof` was removed as an exception) – David C. Rankin Oct 24 '20 at 04:03
  • Thanks everyone, let me just let all of this info sink in and I'll get back to you all. I don't know what some people are talking about because I don't really know much C. I'm only 13 and still learning from a Sams teach yourself book on C. But thanks! – Matthew Schell Oct 24 '20 at 14:51