Zoeken…


Classificeren van karakters gelezen uit een stream

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

typedef struct {
  size_t space;
  size_t alnum;
  size_t punct;
} chartypes;

chartypes classify(FILE *f) {
  chartypes types = { 0, 0, 0 };
  int ch;

  while ((ch = fgetc(f)) != EOF) {
    types.space += !!isspace(ch);
    types.alnum += !!isalnum(ch);
    types.punct += !!ispunct(ch);
  }

  return types;
}

De classify leest tekens uit een stream en telt het aantal spaties, alfanumerieke tekens en leestekens. Het vermijdt verschillende valkuilen.

  • Bij het lezen van een personage uit een stream, wordt het resultaat opgeslagen als een int , omdat er anders een dubbelzinnigheid zou bestaan tussen het lezen van EOF (de einde-van-bestandsmarkering) en een personage met hetzelfde bitpatroon.
  • De functies voor isspace (bijvoorbeeld isspace ) verwachten dat hun argument kan worden weergegeven als een unsigned char , of de waarde van de EOF macro . Aangezien dit precies is wat de fgetc retourneert, is hier geen conversie nodig.
  • De geretourneerde waarde van de functies voor tekenclassificatie maakt alleen onderscheid tussen nul (betekent false ) en niet-nul (betekent true ). Voor het tellen van het aantal keren dat deze voorkomt, moet deze waarde worden omgezet in een 1 of 0, wat wordt gedaan door de dubbele ontkenning, !! .

Tekens uit een string classificeren

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

typedef struct {
  size_t space;
  size_t alnum;
  size_t punct;
} chartypes;

chartypes classify(const char *s) {
  chartypes types = { 0, 0, 0 };
  const char *p;
  for (p= s; p != '\0'; p++) {
    types.space += !!isspace((unsigned char)*p);
    types.alnum += !!isalnum((unsigned char)*p);
    types.punct += !!ispunct((unsigned char)*p);
  }

  return types;
}

De functie classify onderzoekt alle tekens van een tekenreeks en telt het aantal spaties, alfanumerieke tekens en leestekens. Het vermijdt verschillende valkuilen.

  • De functies voor isspace (bijvoorbeeld isspace ) verwachten dat hun argument kan worden weergegeven als een unsigned char , of de waarde van de EOF macro .
  • De uitdrukking *p is van het type char en moet daarom worden omgezet in overeenstemming met de bovenstaande bewoording.
  • Het char type is gedefinieerd als gelijk aan ofwel signed char of unsigned char .
  • Als char gelijk staat aan unsigned char , is er geen probleem, aangezien elke mogelijke waarde van het char type kan worden weergegeven als unsigned char .
  • Wanneer char gelijk is aan signed char , moet het worden omgezet in unsigned char voordat het wordt doorgegeven aan de karakterclassificatiefuncties. En hoewel de waarde van het personage door deze conversie kan veranderen, is dit precies wat deze functies verwachten.
  • De geretourneerde waarde van de functies voor tekenclassificatie maakt alleen onderscheid tussen nul (betekent false ) en niet-nul (betekent true ). Voor het tellen van het aantal keren dat deze voorkomt, moet deze waarde worden omgezet in een 1 of 0, wat wordt gedaan door de dubbele ontkenning, !! .

Invoering

De koptekst ctype.h maakt deel uit van de standaard C-bibliotheek. Het biedt functies voor het classificeren en converteren van tekens.

Al deze functies hebben één parameter nodig, een int die EOF moet zijn of moet kunnen worden weergegeven als een niet-ondertekend teken.

De namen van de classificatiefuncties worden voorafgegaan door 'is'. Elk retourneert een geheel getal niet-nulwaarde (WAAR) als het doorgegeven teken voldoet aan de gerelateerde voorwaarde. Als niet aan de voorwaarde wordt voldaan, retourneert de functie een nulwaarde (FALSE).

Deze classificatiefuncties werken zoals weergegeven, uitgaande van de standaard C-landinstelling:

int a;
int c = 'A';
a = isalpha(c); /* Checks if c is alphabetic (A-Z, a-z), returns non-zero here. */
a = isalnum(c); /* Checks if c  is alphanumeric (A-Z, a-z, 0-9), returns non-zero here. */
a = iscntrl(c); /* Checks is c is a control character (0x00-0x1F, 0x7F), returns zero here. */
a = isdigit(c); /* Checks if c is a digit (0-9), returns zero here. */
a = isgraph(c); /* Checks if c has a graphical representation (any printing character except space), returns non-zero here. */
a = islower(c); /* Checks if c is a lower-case letter (a-z), returns zero here. */
a = isprint(c); /* Checks if c is any printable character (including space), returns non-zero here. */
a = isupper(c); /* Checks if c is a upper-case letter (a-z), returns zero here. */
a = ispunct(c); /* Checks if c is a punctuation character, returns zero here. */
a = isspace(c); /* Checks if c is a white-space character, returns zero here. */
a = isupper(c); /* Checks if c is an upper-case letter (A-Z), returns non-zero here. */
a = isxdigit(c); /* Checks if c is a hexadecimal digit (A-F, a-f, 0-9), returns non-zero here. */
C99
a = isblank(c); /* Checks if c is a blank character (space or tab), returns non-zero here. */

Er zijn twee conversiefuncties. Deze worden genoemd met het voorvoegsel 'to'. Deze functies hebben hetzelfde argument als die hierboven. De retourwaarde is echter geen eenvoudige nul of niet-nul, maar het doorgegeven argument is op een of andere manier gewijzigd.

Deze conversiefuncties werken zoals weergegeven, uitgaande van de standaard C-landinstelling:

int a;
int c = 'A';

/* Converts c to a lower-case letter (a-z). 
 * If conversion is not possible the unchanged value is returned. 
 * Returns 'a' here. 
 */
a = tolower(c);

/* Converts c to an upper-case letter (A-Z). 
 * If conversion is not possible the unchanged value is returned. 
 * Returns 'A' here. 
 */
a = toupper(c);

De onderstaande informatie is geciteerd uit cplusplus.com die in kaart brengt hoe de oorspronkelijke ASCII-set van 127 tekens wordt beschouwd door elk van de classificatietypefuncties (een • geeft aan dat de functie niet-nul retourneert voor dat teken)

ASCII-waarden tekens iscntrl is leeg isspace isupper is lager isAlpha isdigit isxdigit isalnum ispunct isgraph isprint
0x00 .. 0x08 NUL, (andere controle codes)
0x09 tabblad ('\ t')
0x0A .. 0x0D (white-space controle codes: '\ f', '\ v', '\ n', '\ r')
0x0E .. 0x1F (andere controlecodes)
0x20 ruimte (' ')
0x21 .. 0x2F ! "# $% & '() * +, -. /
0x30 .. 0x39 0123456789
0x3a .. 0x40 :;? <=> @
0x41 .. 0x46 ABCDEF
0x47 .. 0x5A GHIJKLMNOPQRSTUVWXYZ
0x5B .. 0x60 [] ^ _ `
0x61 .. 0x66 abcdef
0x67 .. 0x7A ghijklmnopqrstuvwxyz
0x7B .. 0x7E {} ~ Bar
0x7F (DEL)


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow