1
string name,date,dateOfBirth,address,phoneNumber;
int age;
int citizenshipNumber,accountNumber,choiceForMenu;
float amount;
void createAccount(){
    system("cls");
    cout<< setw(40);
    cout<< "ADD RECORD"<<endl;
    cout<<endl;
    printf("Enter today's date(mm/dd/yyyy):");
    scanf("%s" , &date);
    printf("Enter the name:");
    scanf("%s", &name);
    printf("Enter the date of birth(mm/dd/yyyy):");
    scanf("%s" , &dateOfBirth);
    printf("Enter the age:");
    scanf("%d",&age);
    printf("Enter the address:");
    scanf("%s", &address);
    printf("Enter the citizenship number:");
    scanf("%d", &citizenshipNumber);
    printf("Enter the phone number:");
    scanf("%s", &phoneNumber);
    printf("Enter the amount of deposit:");
    scanf("%f", &amount);

    system("pause");
}

After I input the address, the citizenship number, phone number, and amount deposited ends up being on the same line and not allowing me to input anything, so can anyone help me fix that problem. Thank you!

kixsmart
  • 33
  • 4
  • 2
    You cannot use `scanf` with `std::string` (at least not until using C++17 compiler and `data()` method). Why don't you use `std::cin >> date`? – Yksisarvinen Jan 05 '20 at 19:14
  • [Read C++ string with scanf](https://stackoverflow.com/questions/20165954/read-c-string-with-scanf) will answer how to do that, but please don't. Use C++ methods in C++ and C methods in C. – Yksisarvinen Jan 05 '20 at 19:22
  • @Yksisarvinen I can't see a general fix to this with `data()`. Can you expand on that? How do you know how much data to read? – Lightness Races in Orbit Jan 05 '20 at 19:34
  • @LightnessRacesBY-SA3.0 I meant that `data()` in C++17 can return pointer to non-`const`. `scanf` still can overflow the buffer. I'm not exactly sure if the solution provided in answer here is well-defined behaviour either? – Yksisarvinen Jan 05 '20 at 19:41
  • @Yksisarvinen Not sure whether it has an off-by-one problem or not. The fact that it's not immediately clear is reason enough not to use it ;) – Lightness Races in Orbit Jan 05 '20 at 19:43
  • The `"%s"` format specifier is for C-Style strings (arrays of characters). The `scanf` function in C++ does not have format specifiers for `std::string`. – Thomas Matthews Jan 05 '20 at 20:13
  • See `std::string` and `std::getline`. – Thomas Matthews Jan 05 '20 at 20:14

2 Answers2

1

You can' t use scanf with std::string parameter in this way. If you want you can try :

std::string str(50, ' ');
if ( scanf("%*s", &str[0], str.size()) == 1) {
    // ...
}

If you are compiling with c++17 you can try to use data().

But in general these are not the best solutions. In general scanf does not accept any class of C++.

I suggest you to use the C++ methods when use C++, so that you can avoid this error. For example std::cin could be a solution.

Zig Razor
  • 3,381
  • 2
  • 15
  • 35
1

Your code has undefined behavior, as you can't use scanf to read into std::string, but the problem you are reporting is probably independent of that.

When you read a "string" (with either scanf("%s",... or cin >> var where var is a std::string), you are reading a whitespace-delimited token, NOT a line. The call will stop reading as soon as it sees a space or tab (or anything else defined as whitespace in the current locale) after reading at least one non-whitespace character. So if you enter a line with spaces in it (eg, your address contains at least one space), it will stop at that space and leave the rest of the line to be read by future scanf or cin >> calls. As a result, you'll see all your following prompts pile up on a single line as the code reads the rest of the address line as whatever it is that you are reading, rather than waiting for more input lines.

If you want to read lines of input (rather than whitespace delimited text), you should use fgets (C) or getline (POSIX C or C++)

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226