Strings em C

Estou tentando fazer um programa que leia o email de uma pessoa. Porém o e-mail é válido apenas se existir apenas um arroba, ou seja, não pode existir nenhum arroba e nem mais que um arroba. Também, deve existir, pelo menos um ponto. Além disto, tem que haver apenas letras minúsculas. O código que montei, está dando erro. Ele está validando quando eu coloco letras maiúsculas.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
int main()
{
    //Declarações
    char email[100];
    char username[10];
    char password[40];
    int i, arroba;
    //Definindo o comando para acentuação
    setlocale(LC_ALL, "Portuguese");
    //inicializando as variáveis
    arroba = 0;
    //Instruções
//E-MAIL
    printf("Prezado(a) usuário(a), seja bem vindo! Por gentileza, informe o seu e-mail: \n");
    scanf("%s", email);
    printf("O e-mail digitado é: %s \n", email);
    for (i = 0; i < strlen(email); i++){
        if(email[i]=='@'){
            arroba = arroba + 1;
        }
        while(email[i]>='A' && email[i]<='Z' || arroba!=1){
            printf("E-mail digitado é INVÁLIDO. Por favor tente novamente!\n");
            printf("Por gentileza, informe o seu e-mail:\n");
            scanf("%s", email);
            arroba = 0 ;
            for (i = 0; i < strlen(email); i++){
                if(email[i]=='@'){
                arroba = arroba + 1;
            }
            printf("%d\n", arroba);

        }
    }
    }

Eu sugiro organizar melhor o código, criando uma função responsável por validar o email, por exemplo:

// retorna 1 se o email é válido, zero se for inválido
int is_valid(char *email) {
    int arroba = 0;
    int ponto = 0;
    for (int i = 0; email[i] != '\0'; i++) {
        if (email[i] == '@') {
            if (arroba == 1) // tem mais de uma arroba, é inválido
                return 0; // já retorna, nem precisa continuar verificando
            arroba++;
        } else if (email[i] == '.') {
            ponto++;
        } else if ('A' <= email[i] && email[i] <= 'Z') {
            // tem letra maiúscula, é inválido
            return 0; // já retorna, nem precisa continuar verificando
        }
    }
    return ponto > 0; // é válido se tiver pelo menos 1 ponto
}

Aí, basta rodar o while enquanto o email for inválido:

char email[100];
printf("Prezado(a) usuário(a), seja bem vindo! Por gentileza, informe o seu e-mail: \n");
while (1) {
    scanf("%s", email);
    if (is_valid(email)) {
        // email válido, imprime sai do while
        printf("%s é um email válido\n", email);
        break; // sai do while
    } else {
        printf("E-mail digitado é INVÁLIDO. Por favor tente novamente!\nPor gentileza, informe o seu e-mail:\n");
    }
}

Repare também que não usei strlen, pois esta função sempre percorre a string inteira do início ao fim para calcular o seu tamanho. Ou seja, você estará percorrendo a mesma string várias vezes desnecessariamente (problema também conhecido como Shlemiel the painter’s algorithm). Em vez disso, pode simplesmente percorrer a string até encontrar o terminador (o caractere nulo, cujo código é \0).


Vale lembrar que esta validação é bem ingênua, pois ela só verifica a existência de determinados caracteres. Por exemplo, ela nem sequer verifica se tem pelo menos uma letra, então ...@ será considerado um email válido. Mas deu para pegar a ideia, pois aí bastaria adicionar todos os critérios na função is_valid.

2 curtidas

Eu super entendi. Acho que estava fazendo em C algo que não era, de fato em C.
Faz todo sentido o que você explicou!
Muito obrigado, Hugo!

Teria como eu usar esta mesma função para criar a senha?
mas a senha só pode ter letras minúsculas (sem números e caractéres especiais)

Se as regras da senha são diferentes do email, é melhor criar outra função pra validar a senha.