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\$ – user10766 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\$ – user10766 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

|improve this answer|||||
\$\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\$ – user10766 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