-1

I'm attempting to create a program that validates a phone number entered by a user and stores it in a string. The user entering the phone number will be able to enter it as one of the following formats:

(xxx)xxx-xxxx

xxxxxxxxxx

xxx-xxx-xxxx

I can think of several but very tedious ways to validate the phone number ensuring that it follows the specific format. What could be the simplest option?

asa
  • 47
  • 7
  • 2
    "I can think of several but very tedious ways" - share them. Also, this likely belongs to Code Review. – Daniel Kamil Kozar Mar 21 '17 at 22:54
  • 1
    @DanielKamilKozar: Code review would have a serious talk to you if you moved this question. They expect **working** code. I don't see any in the question. – too honest for this site Mar 21 '17 at 23:00
  • @Olaf : I do realise that, which is why I asked the OP to share the code in question first. :) – Daniel Kamil Kozar Mar 21 '17 at 23:02
  • @DanielKamilKozar: Questions like this one will almost certainly not be ready for CR. – too honest for this site Mar 21 '17 at 23:03
  • check this [library from Google](https://github.com/googlei18n/libphonenumber). – Andrey Mar 21 '17 at 23:06
  • @Andrey Looks nice, but the Readme there mentions only C++, not C. – Peter - Reinstate Monica Mar 21 '17 at 23:26
  • I must assume that this is some kind of assignment; any real-world approach would use either a general regular expression library or something like Andrey's dedicated tool. Note that you [can write a C wrapper around a C++ library](http://stackoverflow.com/questions/199418/using-c-library-in-c-code) if you want to. – Peter - Reinstate Monica Mar 21 '17 at 23:28
  • simple solution.. go through the string, add only the number characters to another string, and validate only your new string against a single format instead of worrying about checking for all 3 formats you listed. I assume you won't be dealing with international phone numbers or numbers with letters in them. – yano Mar 21 '17 at 23:33
  • Is `sscanf()` OK to use like `int n = 0; sscanf(buf, "(%*1u%*1u%*1u)%*1u%*1u%*1u-%*1u%*1u%*1u%*1u%n", &n); if (n && buf[n]==0) PassFirstPattern(buf);` ? – chux - Reinstate Monica Mar 22 '17 at 02:55

1 Answers1

2

With re2c, you can specify a regex and have it turned into C.

bool verify(char const *YYCURSOR)
{
    char const*YYMARKER;
    /*!re2c
        re2c:define:YYCTYPE = char;
        re2c:yyfill:enable = 0;
        D = [0-9];  
        '('D{3}')'D{3}'-'D{4} | D{10} | D{3}'-'D{3}'-'D{4} '\x00'      { return 1; }
        * { return 0; } 
    */
}
int main(int argc, char **argv) //test it on main arguments
{
    for(int i=1;i<argc;i++)
        printf("%s\t%d\n", argv[i], verify(argv[i]));
}

Re2c will compile it into a well-oiled finite state machine (by oil, I mean gotos, many gotos):

/* Generated by re2c 0.16 on Wed Mar 22 00:08:21 2017 */
#line 1 "verify.c.re"
bool verify(char const *YYCURSOR)
{
    char const*YYMARKER;

#line 8 "verify.c"
{
    char yych;
    yych = *YYCURSOR;
    switch (yych) {
    case '(':   goto yy4;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy5;
    default:    goto yy2;
    }
yy2:
    ++YYCURSOR;
yy3:
#line 10 "verify.c.re"
    { return 0; }
#line 31 "verify.c"
yy4:
    yych = *(YYMARKER = ++YYCURSOR);
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy6;
    default:    goto yy3;
    }
yy5:
    yych = *(YYMARKER = ++YYCURSOR);
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy8;
    default:    goto yy3;
    }
yy6:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy9;
    default:    goto yy7;
    }
yy7:
    YYCURSOR = YYMARKER;
    goto yy3;
yy8:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy10;
    default:    goto yy7;
    }
yy9:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy11;
    default:    goto yy7;
    }
yy10:
    yych = *++YYCURSOR;
    switch (yych) {
    case '-':   goto yy12;
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy13;
    default:    goto yy7;
    }
yy11:
    yych = *++YYCURSOR;
    switch (yych) {
    case ')':   goto yy14;
    default:    goto yy7;
    }
yy12:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy15;
    default:    goto yy7;
    }
yy13:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy16;
    default:    goto yy7;
    }
yy14:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy17;
    default:    goto yy7;
    }
yy15:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy18;
    default:    goto yy7;
    }
yy16:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy19;
    default:    goto yy7;
    }
yy17:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy20;
    default:    goto yy7;
    }
yy18:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy21;
    default:    goto yy7;
    }
yy19:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy22;
    default:    goto yy7;
    }
yy20:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy23;
    default:    goto yy7;
    }
yy21:
    yych = *++YYCURSOR;
    switch (yych) {
    case '-':   goto yy24;
    default:    goto yy7;
    }
yy22:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy25;
    default:    goto yy7;
    }
yy23:
    yych = *++YYCURSOR;
    switch (yych) {
    case '-':   goto yy19;
    default:    goto yy7;
    }
yy24:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy26;
    default:    goto yy7;
    }
yy25:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy27;
    default:    goto yy7;
    }
yy26:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy28;
    default:    goto yy7;
    }
yy27:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy29;
    default:    goto yy7;
    }
yy28:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy31;
    default:    goto yy7;
    }
yy29:
    ++YYCURSOR;
#line 9 "verify.c.re"
    { return 1; }
#line 373 "verify.c"
yy31:
    yych = *++YYCURSOR;
    switch (yych) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':   goto yy32;
    default:    goto yy7;
    }
yy32:
    ++YYCURSOR;
    if ((yych = *YYCURSOR) <= 0x00) goto yy29;
    goto yy7;
}
#line 12 "verify.c.re"
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142