0

So I have a void function called phone where I want to ask the user to input a 11 digit number starting with 0 where it's possible to have a single gap (eg. 01234567890 or 01234567 890).

void phone()
{
    char number[20];
    printf("Please enter your phone number: ");
    fgets(number, 20, stdin);
    while(number[0] != 0 && (strlen(number) != 11 || strlen(number) != 11 + ' '))
    {
        printf("please try again");
        fgets(number, 20, stdin);
    }
}

This is my current function that I have where I can make it work to accept numbers starting with 0 I can't get the second either or part of the condition to work. I'm relatively new to c so I'm not really sure if there is an easier way to do this. Also if you look at my output it jumps from the first print statement to the second before asking for input, not sure where the fault is there as I have fgets before the while function. output

ursula
  • 15
  • 7
  • 4
    What was the intention behind `strlen(number) != 11 + ' '`? – 500 - Internal Server Error Apr 22 '21 at 12:09
  • The `strlen(number= != 11)` is wrong as 11 is the number of digits but not the length of the src string. Normalize your number before going on. E.g., remove all WS in the src string. You can use the same buffer as you only remove some chars and you do not need to access each char/digit more than one time. – Wör Du Schnaffzig Apr 22 '21 at 12:15
  • The intent was that the string could be 11 characters long with a gap so 12 characters in total. So for example 01234567 890 which is 11 digits with a gap. – ursula Apr 22 '21 at 12:16
  • @pqans Few questions, what does src mean? What does normalizing the number mean? What does WS stand for? I'm very new to coding so I don't understand these terms sorry – ursula Apr 22 '21 at 12:20
  • `src` means source and refers to the input source string provided by the user. WS is whitespace and normalizing refers to modifying the src string in a way that the outcome has the same meaning but in a standard format which does not depend on the format provided by the user. Sorry for throwing with abbreviations at you. ;-) – Wör Du Schnaffzig Apr 22 '21 at 12:26
  • @pqans No worries ^^ but for the output I need an 11 digits number that may or may not have a single WS. Also you mentioned before that 11 is the number of digits but not the length of the source string. Does that mean it should be 12 as when you enter it counts as extra? Or does that mean I have to make char number smaller because I used 20 so that I could give an error so the user could try input again. – ursula Apr 22 '21 at 12:34
  • 1
    `(strlen(number) != 11 || strlen(number) != 11 + ' ')` will always be true because no number will be equal to both `11` and `11 + ' '` at the same time. – MikeCAT Apr 22 '21 at 12:44

3 Answers3

1

You basically want this:

#include <stdio.h>
#include <string.h>           // needed for strcspn

// counts the number of spaces
int spacecount(const char* str)
{
  int count = 0;
  for (int i = 0; str[i] != 0; i++)
  {
    if (str[i] == ' ')
      count++;
  }

  return count;
}

void phone()
{
  char number[20];
  printf("Please enter your phone number: ");
  fgets(number, 20, stdin);
  number[strcspn(number, "\n")] = 0;   // remove the trailing \n

  while (number[0] != '0' || strlen(number) != 11 || spacecount(number) > 1)
  {
    printf("please try again");
    fgets(number, 20, stdin);
    number[strcspn(number, "\n")] = 0;      // remove the trailing \n
  }
}
  • fgets leaves the string with a trailing \n which needs to be removed, that's what number[strcspn(number, "\n")] = 0 does.
  • you need to count the number of spaces your phone number contains and make sure there is no more than one whitespace and that its length is exactly 11 and that it starts with a '0' (ASCII value of 0 digit) and not a 0 which is the NUL character. That's exactly what the number[0] != '0' || strlen(number) != 11 || spacecount(number) > 1 condition does.

You still need to ensure that the user hasn't entered anything other than digits such as letters or other characters. I leave this to you as an exercise.

This addresses your immediate problems, but there is still room for improvement though such as:

  • writing your own fgets that removes the trailing \n
  • doing the validation in a separate function
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • @4386427 yes you're right. Concerning the `abcde` input, this is addressed in the question and left as an exercise. BTW I upvoted your answer, but don't feel obliged to do the same on mine. – Jabberwocky Apr 22 '21 at 14:00
1

There are several problems in your code.

For instance:

number[0] != 0

doesn't check if the first character is the digit/character 0. It checks whether the numeric value is zero. Two very different things...

To check for the digit/character 0 you must do:

number[0] != '0'

Further, this strlen(number) != 11 + ' ' doesn't do anything near what you expect.

In general the check you want to do is far to complex to be a condition in a while statement. I'll suggest that you use a function for the validation. Like:

int number_is_invalid(const char* number)
{
    // add code to validate number
    // return 1 if invalid
    // return 0 if valid
}

void phone()
{
  char number[20];
  printf("Please enter your phone number: ");
  fgets(number, 20, stdin);
  number[strcspn(number, "\n")] = 0;   // remove the trailing \n

  while (number_is_invalid(number))
  {
    printf("please try again");
    fgets(number, 20, stdin);
    number[strcspn(number, "\n")] = 0;      // remove the trailing \n
  }
}

So how could the function look?

Well, perhaps like:

// Function to validate a number
// - A valid number has 11 digit and optionally 1 space
// - A valid number must start with the digit 0
int number_is_invalid(const char* number)
{
    // Must start with the digit 0
    if (*number != '0') return 1; // invalid - doesn't start with digit 0

    int number_of_spaces = 0;
    int number_of_digits = 0;
    while(*number)
    {
        if (*number == ' ')
        {
            ++number_of_spaces;
        }
        else if (*number >= '0' && *number <= '9')
        {
            ++number_of_digits;
        }
        else
        {
            return 1;  // invalid character in input
        }
        ++number;
    }
    if (number_of_digits != 11) return 1; // invalid - wrong number of digits
    if (number_of_spaces > 1) return 1;   // invalid - too many spaces
    return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • Um wasn't really expecting an answer but thank you for the help I sort of understand where I was going wrong by trying to fit it all in one function. So for these sort of problems that require a validation it's ideal to have another function to validate that will link to the main function. Thank you for your help it is much appreciated! ^^ – ursula Apr 22 '21 at 14:30
  • What does `number[strcspn(number, "\n")] = 0;` do? Or what does strcspn do in this line? Looked it up and its defined as "calculates the length of the number of characters before the 1st occurrence of character present in both the string" but if its possible could you please explain that in a simpler way if possible. Many thanks either way ^^ – ursula Apr 22 '21 at 15:02
  • @ursula Read this: https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input – Support Ukraine Apr 23 '21 at 05:23
0

You have the explanation in the code:

int countSpaces(char numbers[])
{
/*
This function counts the spaces from a given char and returns it
*/
int counter=0;
for(int i=0;i<strlen(numbers);i++)
    if(numbers[i]==' ')
        counter++;
return counter;
}

void phone()
{
char number[20];
printf("Please enter your phone number: ");
fgets(number, 20, stdin);
while(number[0] != '0' || strlen(number)-1-countSpaces(number)!= 11 /*|| countSpaces(number)>1*/)
{
    //[1]You compared number[0] != 0 which is always true number[0] is char and is different from 0 because it s int;
    //[2]When you input a char array there will be added '\0' at the end of the array
    //'\0'-represents the end of char array and will be counted so we add -1;
    //[3]We decrease the number of spaces found in the array;
    //[4]If you really want to have exact one space delete the comments from condition
    printf("%d\n",countSpaces(number));
    printf("please try again");
    fgets(number, 20, stdin);
}
}