0

So, I got this assignment as a student that ask me to create a simple program using C. This program input only allow you to input only characters A-Z, a-z, and (space). and the length of the string should be no less than 1 character and no more than 100 characters.

So, I come with the conclusion that I should use if function to validate if the user input the allowed character.

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

int main()
{
    char name[100];

    scanf("%s",&name);
    fflush(stdin);
    if (isdigit(name))
                ^^^^
    {
        printf("Wrong answers");    
        getchar();
    }
    else
        ....

It was supposed to print "wrong answers" if you input numbers in there, but this program won't run.. It keeps saying :

error C2664: 'isdigit' : cannot convert parameter 1 from 'char [100]' to 'int'

I don't know what this error means.. Is there something I miss? Or am I using the wrong function?

I have also tried

if (((name>='A')&&(name<='Z'))||((name>='a')&&(name<='z')||)((name==' ')))
{
  //this print what i want
}
else
{
  printf("wrong answers");//this print "wrong answer"
}

but it always print "wrong answers" no matter I input the correct input or the wrong input.

Your help is highly appreciated. Thank you.

*ps : I am a beginner at programming.

J...S
  • 5,079
  • 1
  • 20
  • 35
  • The type of `name` is an array of `char`, while `isdigit()` expects a single `char`. – kfx Oct 06 '17 at 10:10
  • 1
    Note that `fflush(stdin);` is non-portable and is actually explicitly undefined behavior. Per **7.21.5.2 The `fflush` function**, paragraph 2 of [the C Standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf): "If `stream` points to an output stream or an update stream in which the most `recent` operation was not input, the `fflush` function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; **otherwise, the behavior is undefined**." – Andrew Henle Oct 06 '17 at 10:54
  • Before using a particular function, it might be wise to [RTFM](https://linux.die.net/man/3/isdigit). – Lundin Oct 06 '17 at 11:39
  • Your caps lock key is broken? – nicomp Oct 06 '17 at 13:22

5 Answers5

4

isdigit() takes an int as argument, not a char*:

   int isdigit(int c);

You have to use a loop over the string and check each character in it.

Having said that, to achieve:

this program input only allow you to input only characters 'A'-'Z', 'a'-'z', and ' '(space)

you are better off using isalpha().

P.P
  • 117,907
  • 20
  • 175
  • 238
0

Try this out:

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

int main()
{
    int i = 0;
    char name[101], temp;

    // take input one character at a time    
    while(scanf("%c", &temp)){
        // stop when newline or carriage return
        if(temp == '\n' || temp == '\0' || !isalpha(temp) ){
            break;
        }

        // save character in array
        name[i] = temp;

        // move to the next position of the array
        i++;
    }

    printf( "%s", temp );

    return 0;
}
Hasan Shahriar
  • 468
  • 3
  • 11
0

The problem you're seeing is that you're passing isdigit the wrong type of value - it expects an int, but you're passing it an array of char. You would have to loop over each and every character in your string to check if it's a digit or not.

But that is ultimately not what you're after as you're looking to confirm that the string contains letters or spaces - there are lots of characters that could be entered that aren't classed as digits that would be accepted incorrectly.

What would be the easiest solution for you, is to use the function strspn. It takes a string and returns the length of how many characters match the second parameter. If that length is the same length as your string, you know that it only contains valid characters.

size_t valid;
valid=strspn(name, "abcdefg(fill in with other valid characters)");
if(valid==strlen(name))
  {
  // Valid name
  }
else
  {
  // Not valid
  }

If you need to expand the accepted characters, it's just a simple case of adding them to the 2nd parameter.

Chris Turner
  • 8,082
  • 1
  • 14
  • 18
0

OP's code fails as isdigit() test is a single character is a digit (0-9). It does not test a string.

int isdigit(int c);
The isdigit function tests for any decimal-digit character.
In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF.

OP's buffer is too small to save 100 characters read from the user. At least 1 more needed to detect if too many were read and 1 more for a null character to mark the end of a string.

fflush(stdin); has its problems too.

scanf("%s",&name); does not save white-space. The parameter should have been name too. (no &)


Read a line of user input with fgets() which saves the result as a string. Test if the input meets the criteria.

Read

#define N 100
// No need to be stingy on buffer size reading user input.  Suggest 2x
// We need +1 for extra character detection, \n and \0
char buf[2*N + 1 + 1];
fgets(buf, sizeof buf, stdin);
// lop off potential \n
size_t length = strlen(buf);
if (length > 0 && buf[length-1] == '\n') {
  buf[--length] = '\0';
}

Test

  1. only characters 'A'-'Z', 'a'-'z', and ' '(space).

    for (size_t i = 0; i<length; i++) {
      if (!isalpha((unsigned char)buf[i]) && buf[i] != ' ') {
        puts("Invalid chracter");
        break;
      }
    } 
    
  2. length of the string should be no less than 1 character and no more than 100 characters.

    if (length < 1 || length > 100) {
      puts("Input wrong length");
    } 
    

Others approaches can be used to disqualify very long inputs. IMO, very long inputs represent an attack and should be handled differently than a simple line that was a bit too long.

    if (length < 1 || length > 100) {
      if (length + 2 >= sizeof buf) {
        puts("Input way too long");
        exit (EXIT_FAILURE);
      }
      puts("Input wrong length");
    } 
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

name must have one extra space for the \0 (NUL) character. So to store 100 characters, its size should be at least 101.

char name[101];

You could first use

fgets(name, sizeof(name), stdin);

to read into name character array.

Note that fgets() will read in the trailing newline (\n) as well which need be removed like

name[strlen(name)-1]='\0';

Then use sscanf(). Like

size_t l=strlen(name);
sscanf(name, "%100[A-Za-z ]", name);

if(strlen(name)!=l)
{
    printf("\nInvalid input.");
}

Note the space after the A-Za-z.

The 100 in the %100[A-Za-z] denotes reading at most 100 characters into name. The [A-Za-z ] will make the sscanf() stop reading if a non-alphabetic character which is not a space is encountered.

First read into name. Then store its length in l. Now read everything till a non-alphabet other than a space occurs in name to name itself (thereby modifying name).
Now compare the length of this new string with l. If they are the same. The input is valid as per your need.

You could also use scanf() instead of fgets() like

scanf("%100[^\n]", name);

which instructs to read every character till a \n into name. If this is used, no \n will added at the end of name unlike the case with fgets().

Now I would like to point out some mistakes in your code.

scanf("%s",&name);

will lead to errors. Correct one is

scanf("%s",name);

as the second argument here must be an address and since an array name in C decays into its base address, just name would do instead of &name.

As others have pointed out, using fflush() on stdin is undefined and must be avoided.

If you are trying to clear the input buffer till the next newline (\n), you could do

int ch;
while((ch=getchar())!='\n');// && ch!=EOF)

The argument of isdigit() must be a char and not a character array (type char [100] if size is 100).

And if is a statement and not a function.

J...S
  • 5,079
  • 1
  • 20
  • 35