Sök…


Klassificera tecken lästa från en ström

#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;
}

classify läser tecken från en ström och räknar antalet mellanslag, alfanumeriska och skiljetecken. Det undviker flera fallgropar.

  • När du läser ett tecken från en ström sparas resultatet som ett int , eftersom det annars skulle vara en oklarhet mellan läsning av EOF (markören i slutet av filen) och ett tecken som har samma bitmönster.
  • isspace (t.ex. isspace ) förväntar sig att deras argument antingen kan representeras som ett unsigned char eller värdet på EOF makro . Eftersom det är exakt vad fgetc returnerar, finns det inget behov av omvandling här.
  • Returvärdet för teckenklassificeringsfunktionerna skiljer bara mellan noll (vilket betyder false ) och icke-noll (vilket betyder true ). För att räkna antalet händelser måste detta värde konverteras till en 1 eller 0, vilket görs genom dubbel negation, !! .

Klassificera tecken från en sträng

#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;
}

classify undersöker alla tecken från en sträng och räknar antalet mellanslag, alfanumeriska och skiljetecken. Det undviker flera fallgropar.

  • isspace (t.ex. isspace ) förväntar sig att deras argument antingen kan representeras som ett unsigned char eller värdet på EOF makro .
  • Uttrycket *p är av char och måste därför konverteras för att matcha ovanstående formulering.
  • char definieras som likvärdigt med antingen signed char eller unsigned char .
  • När char motsvarar unsigned char finns det inga problem, eftersom alla möjliga värden av char representeras som unsigned char .
  • När char motsvarar signed char måste den konverteras till unsigned char innan den överförs till karaktärsklassificeringsfunktionerna. Och även om värdet på karaktären kan förändras på grund av denna konvertering, är det exakt vad dessa funktioner förväntar sig.
  • Returvärdet för teckenklassificeringsfunktionerna skiljer bara mellan noll (vilket betyder false ) och icke-noll (vilket betyder true ). För att räkna antalet händelser måste detta värde konverteras till en 1 eller 0, vilket görs genom dubbel negation, !! .

Introduktion

Rubriken ctype.h är en del av standard C-biblioteket. Det tillhandahåller funktioner för klassificering och konvertering av tecken.

Alla dessa funktioner tar en parameter, en int som måste vara antingen EOF eller representerande som ett osignerat char.

Namnen på klassificeringsfunktionerna är förinställda med "är". Var och en returnerar ett heltal som inte är noll (TRUE) om tecknet som skickas till det uppfyller det relaterade villkoret. Om villkoret inte är uppfyllt returnerar funktionen ett nollvärde (FALSE).

Dessa klassificeringsfunktioner fungerar som visas, förutsatt att standardinställningen är C:

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. */

Det finns två konverteringsfunktioner. Dessa namnges med prefixet 'till'. Dessa funktioner har samma argument som ovan. Återkopplingsvärdet är emellertid inte en enkel noll eller en noll utan det godkända argumentet ändras på något sätt.

Dessa konverteringsfunktioner fungerar som visas, förutsatt att standardinställningen är C:

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);

Nedanstående information citeras från cplusplus.com- kartläggning av hur den ursprungliga ASCII-uppsättningen på 127 tecken betraktas av var och en av funktionerna för klassificeringstyp (a • indikerar att funktionen returnerar icke-noll för det tecknet)

ASCII-värden tecken iscntrl ISBLANK isspace isupper islower isalpha isdigit isxdigit isalnum ispunct isgraph isprint
0x00 .. 0x08 NUL, (andra kontrollkoder)
0x09 flik ('\ t')
0x0A .. 0x0D (vitrumsstyrningskoder: '\ f', '\ v', '\ n', '\ r')
0x0E .. 0x1F (andra kontrollkoder)
0x20 Plats (' ')
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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow