Task: Strip control codes and extended characters from a string

C: #include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAXBUF 256  
#define STR_SZ 100   



int ascii (const unsigned char c);

int ascii_ext (const unsigned char c);

unsigned char* strip(unsigned char* str, const size_t n, int ext );


 
int ascii (const unsigned char c) 
{  
  unsigned char min = 32;   
  unsigned char max = 126;  

  if ( c>=min && c<=max ) return 1;

  return 0;
} 


 
int ascii_ext (const unsigned char c) 
{  
  unsigned char min_ext = 128;   
  unsigned char max_ext = 255;

  if ( c>=min_ext && c<=max_ext )
       return 1;

  return 0;
} 




unsigned char* strip( unsigned char* str, const size_t n, int ext) 
{ 

  unsigned char buffer[MAXBUF] = {'\0'};

  size_t i = 0;  
  size_t j = 0;  

  size_t max = (n<MAXBUF)? n : MAXBUF -1;  

  while (i < max )
    {
      if ( (ext && ascii_ext(str[i]) ) ||  (ascii(str[i]) ) )    
	{
	  buffer[j++] = str[i]; 
	}      
      i++;
    }

  memset(str, '\0', max); 

  i = 0;               

  while( i < j)
    {
      str[i] = buffer[i]; 
      i++;
    }

  str[j] = '\0';  

  return str;  
}


int main( int argc, char** argv)
{
  enum {ASCII=0, EXT=1}; 

  unsigned int seed = 134529;  

  
  unsigned char badstring[STR_SZ] = {'\0'};
  unsigned char bs_2[STR_SZ]      = {'\0'};
 
  unsigned char* goodstring = NULL;
  unsigned char* goodstring_ext = NULL;

  size_t i = 0;

  srand(seed); 

  fprintf(stdout, "Original:\t" );

  
  for (i = 0; i < STR_SZ; i++)
    {
      badstring[i] = (unsigned char) ( rand () & (unsigned char)0xFF );
      fprintf(stdout, "%c", badstring[i] );
    }
  fprintf(stdout, "\n");

   
   memcpy(bs_2, badstring, STR_SZ * sizeof(unsigned char) ); 

   goodstring_ext = strip( badstring, STR_SZ, EXT); 

   fprintf(stdout, "\nEXT:\t%s\n" , goodstring_ext );

   goodstring = strip( bs_2, STR_SZ, ASCII); 
  
   fprintf(stdout, "\nASCII:\t%s\n" , goodstring );
  
return 0;
}










Fortran: module stripcharacters
implicit none

contains

  pure logical function not_control(ch)
    character, intent(in) :: ch
    not_control = iachar(ch) >= 32 .and. iachar(ch) /= 127
  end function not_control

  pure logical function not_extended(ch)
    character, intent(in) :: ch
    not_extended = iachar(ch) >= 32 .and. iachar(ch) < 127
  end function not_extended

  pure function strip(string,accept) result(str)
    character(len=*), intent(in) :: string
    character(len=len(string))   :: str
    interface
      pure logical function accept(ch)
        character, intent(in) :: ch
      end function except
    end interface
    integer :: i,n
    str = repeat(' ',len(string))
    n = 0
    do i=1,len(string)
      if ( accept(string(i:i)) ) then
        n = n+1
        str(n:n) = string(i:i)
      end if
    end do
  end function strip

end module stripcharacters


program test
  use stripcharacters
  
  character(len=256) :: string, str
  integer            :: ascii(256), i
  forall (i=0:255) ascii(i) = i
  forall (i=1:len(string)) string(i:i) = achar(ascii(i))
  write (*,*) string
  
  write (*,*) 'Control characters deleted:'
  str = strip(string,not_control)
  write (*,*) str

  forall (i=1:len(string)) string(i:i) = achar(ascii(i))
  write (*,*) 'Extended characters deleted:'
  write (*,*) strip(string,not_extended)
end program test