I want to check if the string contains only letters?

Asked

Viewed 671 times

4

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#define tam 50

main(){
    struct cadastro{
        char nome[tam];
    };
    struct cadastro dados;

    printf("Nome:");
    fgets(dados.nome,tam,stdin);
    fflush(stdin);

    if(isalpha(dados.nome[tam])){  //verificar se são letras
        printf("Nome: %s\n",strupr(dados.nome));  //converter para letra maiuscula
    }else{
        printf("Insira somente letras.\n");
    }

    system("pause > NULL");
    return (0);
}

1 answer

6

You may not use the isalpha how did you use:

if(isalpha(dados.nome[tam])){

So it is using only in a character the 50 which is already outside the valid range in your case, which would be 0 to 49. So you only know if that character is a letter.

To perform the validation you want you must use the isalpha in each character, thus validating if all are letters. I suggest creating a function just for this check:

int apenas_letras(char *texto){
    int i;
    for (i = 0; texto[i] != '\0'; ++i){ //percorrer todos os carateres
        if (!isalpha(texto[i]) && texto[i] != ' '){ //se não for letra nem espaço
            return 0; //retornar 0 indicando que não tem somente letras
        }
    }
    return 1; //retornar 1 indica que só tem letras
}

Note that I have individualized the space so that it is also considered as a letter. You can remove this additional test if that is not your goal.

Now just use on main who already has:

if(apenas_letras(dados.nome)){ //<--aqui
    printf("Nome: %s\n",strupr(dados.nome));  
}else{
    printf("Insira somente letras.\n");
}

Note also that to function properly has to treat the string which is dealt with the fgets because this leaves the \n read at the end, which will interfere with the validation. You can remove it as follows:

size_t tam_nome = strlen(dados.nome);
if (dados.nome[tam_nome - 1] == '\n'){
    dados.nome[tam_nome - 1] = '\0';
}

I leave one last note that the function strupr which you are using is not standard, and which for some operating systems will not be implemented.

Example of this solution in Ideone

I took the strupr on Ideone so it could work

Edit:

As an alternative to strupr I recommend to implement it manually even, since it is a small and considerably simple function. In this sense could implement it so for example:

char* strupr(char *str){
    size_t str_size = strlen(str); //saber o tamanho da que entrou
    //criar espaço para a nova mais o terminador
    char *upr = malloc(sizeof(char) * (str_size + 1));
    if (!upr){ //se não deu para alocar memoria
        return NULL; //retorna NULL como indicando que algo falhou
    }

    int i;
    for (i = 0; str[i] != '\0'; ++i){ //percorrer a antiga
        upr[i] = toupper(str[i]); //converter cada letra para maiuscula
    }
    upr[i] = '\0'; //colocar o terminador no fim da convertida    
    return upr;
}

Conversion to uppercase was done using the function toupper in every letter.

This implementation maintains the semantics of the function strupr which I was using. I in particular do not like this semantics as it is allocated memory within the function with malloc. This implies that unless the program ends next, it will be necessary to release the memory of the string converted with free, under penalty of having a memory leak.

  • what Voce recommends to replace the strupr function?

  • @Tshellsi I edited the answer with my suggestion

Browser other questions tagged

You are not signed in. Login or sign up in order to post.