-1

Do you know how I can detect space and letters in a CHAR variable?

I need to detect letters or space in a input of numbers:

This what I want to do:

Enter Document Number of 8 numbers: 
// i press space and pressed enter
ERROR: please enter the age again: 4fpdpfsg

There's where my code doesn't detect the letters after the 4, and what I want is recognize that there's letters in the input, and then shows only the 4.

int isLetter(char input[]){
    int i = 0;

    while(input[i]!='\0'){
        if((input[i]!=' ') && (input[i]<'a'||input[i]>'z') && (input[i]<'A'||input[i]>'Z'))
        return 0;
        i++;
    }

    return 1;
}
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Alexander
  • 37
  • 1
  • 4
  • 2
    Try `isalpha` and similar family of functions. – Weather Vane Apr 17 '17 at 20:22
  • 1
    What is the issue with you code? Does it run? Does it give wrong results? – Ajay Brahmakshatriya Apr 17 '17 at 20:26
  • run but for example the input should detect as correct 8 "numbers" no letters just numbers like that 12345678 but if i write 1234abcd detects only 1234 and doesnt give error message with input. – Alexander Apr 17 '17 at 20:40
  • 1
    You're working much too hard; [strtoul](https://linux.die.net/man/3/strtoul) is the library function you don't know you need. – zwol Apr 17 '17 at 20:51
  • Also see [Check if User Inputs a Letter or Number in C](https://stackoverflow.com/q/1478932/608639). – jww Jun 02 '18 at 21:42

4 Answers4

4

The standard C library has various character type testing functions. They are declared in the #include <ctype.h> header.

Unfortunately, the obvious way of using these functions is often wrong. They take an argument of type int which is actually expected to be an unsigned character value (a byte, effectively) in the range 0 to UCHAR_MAX. If you pass in a char value which happens to be negative, undefined behavior ensues, which might work by coincidence, crash or worse yet form a vulnerability similar to heartbleed (possibly worse).

Therefore the cast to (unsigned char) is quite likely necessary in the following:

#include <ctype.h>
/* ... */
  char ch;
  /* ... */
  if (isalpha((unsigned char) ch) || ch == ' ') {
    /* ch is an alphabetic character, or a space */
  }

Simple character constants (not numeric escaped ones) derived from the C translation time character set have positive values in the execution environment; code which can safely assume that it only manipulates such characters can do without the cast. (For instance, if all the data being manipulated by the program came from string or character literals in the program itself, and all those literals use nothing but the basic C translation time character set.)

That is to say, isalpha('a') is safe; a is in the C translation time character set, and so the value of the character constant 'a' is positive. But say you're working with source code in ISO-8859-1 and have char ch = 'à';. If char is signed, this ch will have a negative value, which is fine according to ISO C because an accented à isn't in the basic C translation character set. The expression isalpha(ch); then passes a negative value to the isalpha function, which is wrong.

Community
  • 1
  • 1
Kaz
  • 55,781
  • 9
  • 100
  • 149
2

Try:

if (!((input[i] == ' ') || (input[i] >= 'a' && input[i] <= 'z') || (input[i] >= 'A' && input[i] <= 'Z')))

or, better:

#include <ctype.h>
if (!((input[i] == ' ') || isalpha(input[i])))
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
work.bin
  • 1,078
  • 7
  • 29
0

You could use sscanf(input,"%d%n",&number,&nrOfDigits) which reads in an integral value into number and additionally stores the position of the first character which has not been part of the number in nrOfDigits. With this information, you can then decide what to do, e.g. nrOfDigits < 8 would indicate that either the input was shorter than 8 characters, or that it does contain less than 4 consecutive digits. See sample code of the usage below.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int isLetter(char input[]){

    int nrOfDigits=0;
    int number;
    int scannedElems = sscanf(input,"%d%n",&number,&nrOfDigits);
    if (scannedElems == 0) {// number could not be read--
        printf ("No number read.\n");
        return 0;
    }
    else {
        char c = input[nrOfDigits];
        int isAlpha = isalpha(c);
        printf("input %s leads to number %d with %d digit(s); first characer after the digits is '%c', (isalpha=%d)\n", input, number, nrOfDigits, c, isAlpha);
        return number;
    }
}


int main(){

    isLetter("4fpdpfsg");  // input 4fpdpfsg leads to number 4 with 1 digit(s); first characer after the digits is 'f', (isalpha=1)
    isLetter("afpdpfsg"); // No number read.
    isLetter("12345678"); // input 12345678 leads to number 12345678 with 8 digit(s); first characer after the digits is '�', (isalpha=0)
    return 0;
}

BTW: you could implement a similar logic with strtoul as well.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
0

hey guys i finally get the way to detect the input is conformed only for 8 numbers theres the code

char* InputDni(char dni[])
{
    int sizeletter;
    int i;

    fflush(stdin);
    gets(dni);

    // 8 is the size of DNI in argentina

    while((isLetter(dni)) || (strlen(dni)!=8))
    {
        printf("ERROR: enter again the DNI: ");
        fflush(stdin);
        gets(dni);
    }

    sizeletter=strlen(dni);

    for(i=0 ;i<sizeletter; i++)
    {
        while(isalpha(dni[i]))
        {
            printf("ERROR: enter again the DNI: ");
            fflush(stdin);
            gets(dni);
            i++
        }
    }

    return dni;
}

//isLetter

int isLetter(char input[])
{
    int i = 0;
    int sizeletter;
    int flag=1;

    sizeletter=strlen(input);

    for(i=0;i<sizeletter;i++)
    {
        if((input[i]!=' ') && (input[i]<'a'||input[i]>'z') && (input[i]<'A'||input[i]>'Z'))
        {
            flag=0;
        }
    }

    return flag;
}

picture of the code running in cmd:

code running

Alexander
  • 37
  • 1
  • 4