How to write an equivalent to PHP count_chars(string $string, int $mode = 0): array|string function in C

1 Answer

0 votes
#include <stdio.h>

#define ASCII_RANGE 256

// Count characters and produce different outputs depending on mode
// Mode 0,1,2: fill freq array
// Mode 3,4: fill output string
void count_chars(const char *input, int mode, int freq[ASCII_RANGE], char *out_str) {
    // Reset frequencies
    for (int i = 0; i < ASCII_RANGE; i++) {
        freq[i] = 0;
    }
    // Count frequencies
    for (const unsigned char *p = (const unsigned char*)input; *p; p++) {
        freq[*p]++;
    }
    if (mode == 3) { // used characters string
        int pos = 0;
        for (int i = 32; i < 127; i++) { // only printable
            if (freq[i] > 0) {
                out_str[pos++] = (char)i;
            }
        }
        out_str[pos] = '\0';
    } else if (mode == 4) { // unused characters string
        int pos = 0;
        for (int i = 32; i < 127; i++) { // only printable
            if (freq[i] == 0) {
                out_str[pos++] = (char)i;
            }
        }
        out_str[pos] = '\0';
    }
}

// Unified print function
// mode = 0 → all characters
// mode = 1 → only used characters
// mode = 2 → only unused characters
// printable_only = 1 → restrict to ASCII 32–126
void print_array(const int freq[ASCII_RANGE], int mode, int printable_only) {
    int start = printable_only ? 32 : 0;
    int end   = printable_only ? 127 : ASCII_RANGE;
    for (int i = start; i < end; i++) {
        int condition = 1;
        if (mode == 1 && freq[i] <= 0) condition = 0; // used only
        if (mode == 2 && freq[i] != 0) condition = 0; // unused only
        if (condition) {
            printf("'%c' (%d): %d\n", (char)i, i, freq[i]);
        }
    }
}

int main(void) {
    const char *text = "It's the perfect time to start";
    int freq[ASCII_RANGE];
    char buffer[ASCII_RANGE + 1];

    // Mode 1: Only used characters and their frequencies
    printf("Mode 1: Used characters only\n");
    count_chars(text, 1, freq, buffer);
    print_array(freq, 1, 1);

    // Mode 2: Unused characters
    printf("\nMode 2: Unused characters\n");
    count_chars(text, 2, freq, buffer);
    print_array(freq, 2, 1);

    // Mode 3: String of used characters
    printf("\nMode 3: String of used characters: ");
    count_chars(text, 3, freq, buffer);
    printf("%s\n", buffer);

    // Mode 4: String of unused characters
    printf("\nMode 4: String of unused characters: ");
    count_chars(text, 4, freq, buffer);
    printf("%s\n", buffer);

    return 0;
}




/*
run:

Mode 1: Used characters only
' ' (32): 5
''' (39): 1
'I' (73): 1
'a' (97): 1
'c' (99): 1
'e' (101): 4
'f' (102): 1
'h' (104): 1
'i' (105): 1
'm' (109): 1
'o' (111): 1
'p' (112): 1
'r' (114): 2
's' (115): 2
't' (116): 7

Mode 2: Unused characters
'!' (33): 0
'"' (34): 0
'#' (35): 0
'$' (36): 0
'%' (37): 0
'&' (38): 0
'(' (40): 0
')' (41): 0
'*' (42): 0
'+' (43): 0
',' (44): 0
'-' (45): 0
'.' (46): 0
'/' (47): 0
'0' (48): 0
'1' (49): 0
'2' (50): 0
'3' (51): 0
'4' (52): 0
'5' (53): 0
'6' (54): 0
'7' (55): 0
'8' (56): 0
'9' (57): 0
':' (58): 0
';' (59): 0
'<' (60): 0
'=' (61): 0
'>' (62): 0
'?' (63): 0
'@' (64): 0
'A' (65): 0
'B' (66): 0
'C' (67): 0
'D' (68): 0
'E' (69): 0
'F' (70): 0
'G' (71): 0
'H' (72): 0
'J' (74): 0
'K' (75): 0
'L' (76): 0
'M' (77): 0
'N' (78): 0
'O' (79): 0
'P' (80): 0
'Q' (81): 0
'R' (82): 0
'S' (83): 0
'T' (84): 0
'U' (85): 0
'V' (86): 0
'W' (87): 0
'X' (88): 0
'Y' (89): 0
'Z' (90): 0
'[' (91): 0
'\' (92): 0
']' (93): 0
'^' (94): 0
'_' (95): 0
'`' (96): 0
'b' (98): 0
'd' (100): 0
'g' (103): 0
'j' (106): 0
'k' (107): 0
'l' (108): 0
'n' (110): 0
'q' (113): 0
'u' (117): 0
'v' (118): 0
'w' (119): 0
'x' (120): 0
'y' (121): 0
'z' (122): 0
'{' (123): 0
'|' (124): 0
'}' (125): 0
'~' (126): 0

Mode 3: String of used characters:  'Iacefhimoprst

Mode 4: String of unused characters: !"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHJKLMNOPQRSTUVWXYZ[\]^_`bdgjklnquvwxyz{|}~

*/

 



answered 14 hours ago by avibootz
edited 13 hours ago by avibootz
...