0
#include <stdio.h>
#include <string.h>

int main(void) {
    char string[1024];
    int len = 0;
    int i = 0;
    while (fgets(string, sizeof(string), stdin) != 0);
    len = strlen(string) - 1;
    if (len % 2 == 0) {
    printf("%s", string);
    }
}

The aim of this code is to print out inputs that have an even number of characters and omit anything else (will not print it). The program works when there is no space in the string however once I place a space it counts it as the length which I'm trying to stop. How do I make this program omit spaces when counting the length of the string?

  • This simply isn’t what `strlen` is designed to do. Since C does not include a predefined function to “count non-whitespace characters in a string”, you’ll have to implement the function yourself. – Konrad Rudolph Sep 15 '22 at 08:57
  • How would you suggest designing a function that does that? – Dunkle Nacht Sep 15 '22 at 08:58
  • Just loop through each character of the string from the first character, terminating at the null terminator. Check each character and increment a counter (initialized to 0) for the valid ones. – Ian Abbott Sep 15 '22 at 09:20
  • Welcome to SO. Your code doesn't do what you expect it to do regardless what `strlen` does. Your compiler should warn you about a stray `;` after your `while` loop. – Gerhardh Sep 15 '22 at 09:22
  • Note that `while (fgets(string, sizeof(string), stdin) != 0);` is an infinite loop should end-of-file immediately occur. – chux - Reinstate Monica Sep 15 '22 at 09:57

5 Answers5

2

How do I make the strlen() function not count spaces?

The standard function strlen() simple does not do that. Easy to code a new function that does.

#include <ctype.h>
#include <stddef.h>

size_t spaceless_strlen(const char *s) {
  size_t len = 0;
  const unsigned char *us = (const unsigned char *) s;
  while (*us) {
    if (*us != ' ') len++;
    // Or if not counting white-spaces
    if (!isspace(*us)) len++;
    us++;
  }
  return len;
}

Best to pass unsigned char values to is...() functions so a unsigned char * pointer was used.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Regarding how you can achieve counting characters that are not spaces, you can try this.

#include <stdio.h>
#include <string.h>

int main(void) {
    char string[1024];
    int len;
    int count=0;
    int i;
    while (fgets(string, sizeof(string), stdin) != 0){
    len = strlen(string) ;
    for (i=0; i<len;i++)
    {
        if (string[i]!=' ')
            count++;
    }
    if (count % 2 == 0) 
    {
        printf("%s", string);
    }
}
    return 0;
}

Note: In my opinion, this isn't the most optimal way to achieve so but I tried to keep it based on your code and logic!

This seems better : EDIT : it is if you replace the get function with fgets as you initially did!

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char str[1024];
    int i=0,count=0;
    printf("Enter a String\n");
    gets(str);
    while(str[i]!='\0')
    {
        if(str[i]!=' ')
        {
            count++;
        }
        i++;
    }
  if(count% 2 ==0)
  {
   printf("%s ",str,);
  }
  return 0;
}
bylal
  • 161
  • 10
  • 2
    Do not use gets. [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – CGi03 Sep 15 '22 at 09:54
  • bylal, `gets()` is no longer part of the C standard library since C11. – chux - Reinstate Monica Sep 15 '22 at 09:55
0

It is possible to make a dedicated function using fgetc() instead of calling fgets() which returns the read string and its length (without counting the spaces):

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

static int my_fgets(char *s, int size, FILE *stream)
{
  char c;
  int len;
  char *in;

  if (!s || (size <= 0)) {
    return 0;
  }

  len = 0;
  in = s;

  do {

    c = fgetc(stream);
    if ((len < (size - 1)) && (c != EOF) && (c != '\n')) {

      if (!isspace(c)) {
        len ++;
      }

      *(in ++) = c;

    }

  } while ((len < (size - 1)) && (c != EOF) && (c != '\n'));

  *in = '\0';

  return len;
}

int main(void) {
    char string[1024];
    int len = 0;
    int i = 0;
    len = my_fgets(string, sizeof(string), stdin);;
    if (len % 2 == 0) {
      printf("%s, len=%d\n", string, len);
    }
}
Rachid K.
  • 4,490
  • 3
  • 11
  • 30
0

The trick is to only count characters you want. strlen() counts all characters. Write yourself a function:

#include <string.h>

size_t count( const char * s, int (*f)( int ) )
//
// Return the number of elements in the c-string
// `s` that satisfy the predicate function `f()`.
// The function type matches the Standard Library 
// character classification functions in <ctype.h>.
{
  size_t result = 0;
  while (*s) result += f( *s++ );
  return result;
}

With that in hand, you need a predicate function that will return 1 for non-whitespace characters, and 0 for whitespace characters. Easy enough:

#include <ctype.h>

int not_isspace( int c )
{
  return !isspace( c );
}

Now you can totally count the number of non-whitespace characters in your string:

int length = count( s, &not_isspace );

That’s it!

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39
0

If you aren't super-concerned about performance, the easiest to read version might be to call strchr repeatedly in a loop, count the spaces and then subtract them from the string length. Example:

size_t spaceout (const char* original)
{
  size_t spaces = 0;
  for(char* str=strchr(original,' '); str!=NULL; str=strchr(str+1,' '))
  {
    spaces++;
  }
  return strlen(original) - spaces;
}

This only looks for ' ' and it actually iterates over the string twice because of the final strlen call. But the code is quite easy to read.

A possible micro-optimization would be to pass the string length as parameter in case the caller already knows it.

Lundin
  • 195,001
  • 40
  • 254
  • 396