Validating e-mail address input in C I have this little function to validate e-mail. It's a little piece of code to search major mistakes in e-mail input and it's part of a bigger program I have to complete as a school assignment. Is there a better way to do it in C? 

I'd like to do it in regex but if I have understood correctly,  C under Windows doesn't support complex regex. And I use scanf to make testing this code simpler. Later, I replace it with another function that reads user input. Test is an array test[40] that is declared in main.

In addition there is a compiler warning about my for loop, that value computed is not used. It probably means *ch. I use it to end for loop when *ch reaches '\0'. I know I could use while loop. However, is there a solution to fix that or a workaround or a better solution using for loop? And I'd like to know, what would you do differently or what would you also check in addition to what I am checking in my code.

int test(char test[])
{
    int     i;
    char    *pos1, *pos2;
    char    *ch;

    puts("Enter email!");
    scanf("%39s", test);

    while (1) {
        for (i = 0, ch = test; *ch; *ch++) {
                if (*ch == '@') {
                    pos1 = ch;  // &lt;-stores last @ address
                    i++;
                }
            }
            pos2 = ch;          // &lt;-stores end address ("\0") of test

        /* If there is only one "@" */
        if (i == 1) {

            /* Pos1 - test &lt;-a character must be before "@". Ch - pos1 &lt;-Counts
             * backwards from the end of the string towards "@". A character
             * must be between "@" and "." */
            while (pos1 - test &amp;&amp; ch - pos1 &gt; 1) {

                /* From the end of string to "." has to be atleast 2 chars */
                if ((pos2 - ch) &gt; 2 &amp;&amp; *ch == '.') {
                    printf("pos2 - ch is %d and *ch is %c",pos2 - ch, *ch);
                    return 1;
                }
                ch--;
            }
        }
        puts("Email wrong! Enter again");
        scanf("%39s", test);
    } /* End while */

    return 1;
}
Formatting


for (i = 0, ch = test; *ch; *ch++) {
        if (*ch == '@') {
            pos1 = ch;  // &lt;-stores last @ address
            i++;
        }
    }
    pos2 = ch;



You have an extraneous level of indentation in there that throws out that block.


int     i;
char    *pos1, *pos2;
char    *ch;



This is a weird indentation level, it doesn't match anything else and is unnecessary. It literally just complicates how you read it.



Naming


int test(char test[]):



Naming both your function and variables test is bad practice. How am I meant to tell as an outsider reading your code what it is that your code does.


/* Pos1 - test &lt;-a character must be before "@". Ch - pos1 &lt;-Counts
 * backwards from the end of the string towards "@". A character
 * must be between "@" and "." */



If you feel the need to explain your code with comment blocks like this, you can probably improve your naming.

Name your variables as to what they are. For Example: charactersAfterAt.



Duplicate Logic


scanf("%39s", test);
while(1){
    // ...
    scanf("%39s", test);
}



You can reduce duplicate logic by declaring the scan inside the loop at the top.