4
\$\begingroup\$

This challenge challenges you to write a function that will take as its argument an array that specifies the types of input, an optional prompt, and a verification key; inputs and validates the values; and returns them.

Input types:

b - Boolean values.
c - Characters.
i - Integer values, rejects floating point values.
f - Floating point values, accepts integers.
n - Strings that only contain the characters a-z and A-Z, suitable for names.
s - Strings with any character type.
d - Dates in the form of dd/mm/yyyy, leap years and dates previous to 01/01/1900 can be rejected.

Examples:

b - Takes input as specified values, validates it, and returns "0" (false) or "1" (true).
c - Accepts any character.
i - Accepts any integer or number that, when the decimal is dropped, the resulting number is identical to the original number, such as 3 or 90.0. Rejects all other floating point values, such as 4.2 and 5.009.
f - Accepts any floating point or integer values. Floating point values include any number with a decimal value between .1 and .9. Numbers with .0 can count as a integer.
n - Accepts any string that contains only the characters a-z and A-Z. This input will accept "Name," but reject "Name1" and "My name."
s - Accepts any type of string.
d - Accepts any valid date of the form dd/mm/yyyy, such as 03/01/2014.

The function will take an array, vector, or other variable length type as an argument. Each element of the array will contain sub-elements of the input type request input type, an optional prompt, and for the input types s, i, and f, an optional validation format. Input type b must include a validation format in the form of "True/False". The array must be formatted as {type, prompt, validation}.

If no prompt is given, the function will use "> " as a prompt.

If a validation format for input type s is given, it can contain any character that must be matched exactly and a request for any number of characters matching certain criterion. To request the string to have a specific number alphabetic characters (a-z and A-Z), use the format %(number of characters)(c), as in %6c, which requests 6 characters. To request that the input be a certain number of single-digit integers, use %(number of digits)(i), as in %6i, which requests six digits. Any other character given must be matched directly, where i equals i and - equals -". Use %% to signify % because % alone is used to represent a command, as above. These rules can be combined, where i%6c-%%%2ixx represents an input matching i + 6 characters + -% + 2 digits + xx, where ifizlwi-%62xx is a valid example.

Input validation formats for types i and f must be the in the form lowest/highest, where lowest is the lowest acceptable number and highest is the highest acceptable number. Example: 6/50 would require a number between 6 and 50 (inclusive) to be input.

The function will return an array of strings that can be parsed by your program.

Return formatting:

b - Returns "0" (false) or "1" (true).
c, i, f, n, s, l, and d - returns input formatted as string.

Example call:

String s[][] = {{"n", "First name: "}
           {"n", "Last name: "}
           {"i", "Age: "}
           {"d", "Date (dd/mm/yyyy): "}
           {"s", "ISBN: ", "%1i-%6i-%2i-%1i"}
           {"b", "Check out: ", "Yes/No"}};

String[] response = input(s);

The Boolean input will give the options as part of the prompt by displaying the input request as "(True/False)" after the prompt. The above example will display as

"Check out: (Yes/No)"

The function must continue requesting input until a valid input for each request is given.

No internet resources are allowed.

Any input-functions in any language that input and validate any type must not be used. E.g. if a language contains a function to input and validate an integer besides the traditional input function (System.in, cin>>, input(), etc.), that function must not be used. You must do the validation yourself.

No trolling-style answers allowed. There are plenty of trolling questions for you to have fun with.

Shortest code that correctly inputs each of the specified types wins.

\$\endgroup\$
  • \$\begingroup\$ Why the change from the sandbox title? This one is a lot less accurate in describing what you want the program to do. \$\endgroup\$ – Jonathan Van Matre Mar 3 '14 at 18:09
  • \$\begingroup\$ @JonathanVanMatre Because the other was only 14 characters. \$\endgroup\$ – Hosch250 Mar 3 '14 at 18:09
  • \$\begingroup\$ What do you define as a boolean value? Is 0, false, 'false', '', 'off', '0' all boolean values which evaluate as false? \$\endgroup\$ – Ismael Miguel Mar 3 '14 at 23:19
  • \$\begingroup\$ @IsmaelMiguel Just return the string "0" for false because all the values have to be returned in a string array. Otherwise, how could you return all the values? Use "1" for true. \$\endgroup\$ – Hosch250 Mar 3 '14 at 23:27
  • \$\begingroup\$ @hosch250 Which input is a valid boolean input? \$\endgroup\$ – Ismael Miguel Mar 3 '14 at 23:33
2
\$\begingroup\$

C++, 4011 characters

This is the function:

#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<string>i(int a,const string s[][3]){vector<string>q;for(int i=0;i<a;i++){string t,r,f;cout<<(s[i][1]!=""?s[i][1]:"> ");if(s[i][0]=="b"){bool b=1;for(int j=0;j<s[i][2].size();j++){if(b&s[i][2][j]==47){b=0;continue;}b?r+=s[i][2][j]:f+=s[i][2][j];if(b&j==s[i][2].size()-1|!b&s[i][2][j]==47){b=1;q.push_back("0");}}if(s[i][2].size()==0||s[i][2][s[i][2].size()-1]==47||s[i][2][0]==47){b=1;q.push_back("0");}if(b)cin.putback('\n');while(!b){cout<<"("<<s[i][2]<<") ";cin>>t;if(t==r|t==f){q.push_back(t==r?"1":"0");break;}cout<<"Please enter "<<r<<" or "<<f<<".\n"<<(s[i][1]==""?"> ":s[i][1]);}}if(s[i][0]=="c"){while(t.size()!=1){cin>>t;if(t.size()>1)cout<<"Please enter a character.\n"<<(s[i][1]==""?"> ":s[i][1]);}q.push_back(t);}if(s[i][0]=="i"){double d;int j,l=0,b=0;bool x=1;if(s[i][2].size()>2){for(int j=0;j<s[i][2].size();j++){int k=s[i][2][j];if((k<47|k>57)&k!=45){b=0;break;}if(k==45){if(j==0||s[i][2][j-1]==47)l++;else{b=0;break;}}if(k==47){if(j==0||s[i][2][j-1]==45||j==s[i][2].size()-1){b=0;break;}else{b++;x=0;continue;}}x?r+=s[i][2][j]:f+=s[i][2][j];}}if(b==1){x=1;l=stoi(r);b=stoi(f);}else x=0;l>b?x=0:"";while(1){cin>>r;for(int k=0;k<r.size();k++){if(!isdigit(r[k])&r[k]!=45){d=.5;break;}else d=stod(r);}j=d;if(!cin|j!=d|(x&&(j<l|j>b))){cin.clear();getline(cin,t);cout<<"Please enter an integer";if(!x)cout<<".\n";else cout<<" in the range of "<<l<<" and "<<b<<endl<<(s[i][1]==""?"> ":s[i][1]);}else break;}q.push_back(to_string(j));}if(s[i][0]=="f"){double d,l=0,b=0;bool x=1;if(s[i][2].size()>2){for(int j=0;j<s[i][2].size();j++){int k=s[i][2][j];if(k<45|k>57){b=0;break;}if(k==45){if(j==0||s[i][2][j-1]==47)l++;else{b=0;break;}}if(k==47){if(j==0|s[i][2][j-1]==45|j==s[i][2].size()-1){b=0;break;}else{b++;x=0;continue;}}if(x)r+=s[i][2][j];else f+=s[i][2][j];}}if(b==1){x=1;l=stod(r);b=stod(f);}else x=0;l>b?x=0:"";while(1){cin>>r;for(int k=0;k<r.size();k++){if(r[k]<45|r[k]>57|r[k]==47){cin.putback('k');cin>>d;break;}else d=stod(r);}if(!cin||(x&&(d<l|d>b))){cin.clear();getline(cin,t);cout<<"Please enter a floating point number";if(!x)cout<<".\n";else cout<<" in the range of "<<l<<" and "<<b<<endl<<(s[i][1]==""?"> ":s[i][1]);}else break;}q.push_back(to_string(d));}if(s[i][0]=="n"){bool b=1;while(b){cin>>t;for(int j=0;j<t.size();j++){if(!isalpha(t[j])){cout<<"Please enter a string with only letters.\n"<<(s[i][1]==""?"> ":s[i][1]);break;}if(j==t.size()-1)b=0;}}q.push_back(t);}if(s[i][0]=="s"){for(int j=0;j<s[i][2].size();j++){if(s[i][2][j]==37){if(s[i][2][j+1]>47&s[i][2][j+1]<58){int n=s[i][2][j+1]-48;if(s[i][2][j+2]!=99&s[i][2][j+2]!=105){r="";break;}for(int k=0;k<n;k++){r+='%';r+=s[i][2][j+2];}j+=2;}else if(s[i][2][j+1]==37){r+="%%";j+=1;}else{r="";break;}}else r+=s[i][2][j];}while(1){getline(cin,t);if(r.size()!=0){int j=0,k=0;for(;j<r.size();j++){if(r[j]==37){j++;if(r[j]==105){if(t[k]<48|t[k]>57){j=-1;break;}else{k++;continue;}}if(r[j]==99){if(!(t[k]>64&t[k]<91|t[k]>96&t[k]<123)){j=-1;break;}else{k++;continue;}}}if(r[j]==t[k])k++;else{j=-1;break;}if(j==r.size()-1^k==t.size()){j=-1;break;}}if(j!=-1)break;cout<<"Please enter a string in the format "<<r<<"\nThe % signs indicating special characters.\nIf the symbol after the % sign is %, enter %;\nif it is i, enter any digit between 0 and 9 (inclusive);\notherwise, enter any alphabetical charater a-z or A-Z.\n"<<(s[i][1]==""?"> ":s[i][1]);}else break;}q.push_back(t);}if(s[i][0]=="d"){bool x=1;while(1){string d,m,y;int a,b,c;cin>>t;if(t.size()==10&&t[2]==47&t[5]==47){for(int j=0;j<10;j++)if(t[j]<47|t[j]>57){x=0;break;}if(x){d+=t[0];d+=t[1];a=stoi(d);m+=t[3];m+=t[4];b=stoi(m);y+=t[6];y+=t[7];y+=t[8];y+=t[9];c=stoi(y);if(c>1900&a>0){if((b==1|b==3|b==5|b==7|b==8|b==10|b==12)&a<32)break;if((b==4|b==6|b==9|b==11)&a<31)break;if(b==2&((c%4==0&c%100!=0&a<30)|(c%400==0&a<30)|a<29))break;}}}cout<<"Please enter a date after 01/01/1900 in the form dd/mm/yyyy.\n"<<(s[i][1]==""?"> ":s[i][1]);}q.push_back(t);}if(s[i][0]!="s")getline(cin,t);}return q;}

Run it with this as main():

int main() try{

    const int args = 10;
    string s[args][3];

    s[0][0]="b",s[0][1]="",s[0][2]="yes/no";
    s[1][0]="c",s[1][1]="Enter a character: ";
    s[2][0]="i";
    s[3][0]="i",s[3][1]="",s[3][2]="4/6";
    s[4][0]="f";
    s[5][0]="f",s[5][1]="",s[5][2]="-2.4/6.3";
    s[6][0]="n",s[6][1]="";
    s[7][0]="s",s[7][1]="",s[7][2]="rt%%%1c%2id";
    s[8][0]="s",s[8][1]="";
    s[9][0]="d",s[9][1]="Enter a date: ";

    vector<string>v=i(args,s);

    for(int i=0;i<args;i++)cout<<v[i]<<endl;
}
catch(exception&e){cerr<<"Error: "<<e.what()<<endl;}
catch(...){cerr<<"Unknown error.\n";}

enter image description here

\$\endgroup\$
  • \$\begingroup\$ About 1000 of these characters are a little redundant. I made it validate in leap years, and I checked the custom validation values for the correct format to ensure there wouldn't be errors. If there were errors, b returns false as default and the rest ignore the custom validation. \$\endgroup\$ – Hosch250 Mar 8 '14 at 23:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.