How to resolve the algorithm Abbreviations, simple step by step in the C programming language
How to resolve the algorithm Abbreviations, simple step by step in the C programming language
Table of Contents
Problem Statement
The use of abbreviations (also sometimes called synonyms, nicknames, AKAs, or aliases) can be an easy way to add flexibility when specifying or using commands, sub─commands, options, etc.
For this task, the following command table will be used:
Notes concerning the above command table:
For a user string of: the computer program should return the string:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Abbreviations, simple step by step in the C programming language
This C code is designed to perform command matching and provides a foundation for implementing a command-line interpreter. I'll break down each section of the code:
-
Command Table:
- A constant string
command_table
stores a list of commands and their minimum lengths, separated by spaces. - Examples include "add 1" and "find 1", where "1" represents the minimum length for the command.
- A constant string
-
Command Data Structure:
command_t
is a custom data structure representing a command.- Each command has a
cmd
field for the command string,length
for its length,min_len
for its minimum acceptable length, and anext
field to link commands together.
-
Command Matching Function:
command_match()
checks if a given stringstr
matches a command in the linked listcommand
.- It compares the length and content of
str
to the command'slength
andcmd
.
-
String Manipulation Functions:
uppercase()
converts a string to uppercase, ensuring case-insensitive matching.fatal()
is a helper function to print an error message and exit the program.
-
Memory Management Functions:
xmalloc()
andxrealloc()
are wrappers aroundmalloc()
andrealloc()
, respectively, that handle memory allocation and check for errors.
-
Word Splitting Function:
split_into_words()
takes a stringstr
and splits it into an array of words, handling spaces and empty words.
-
Command List Creation:
make_command_list()
reads thecommand_table
string and constructs a linked list ofcommand_t
structures, initializing their properties.
-
Command List Freeing:
free_command_list()
releases the memory allocated for the command list, including the command strings.
-
Command Lookup Function:
find_command()
searches the command list for a command that matches a given wordword
.
-
Testing Function:
test()
takes a command list and an input string, and iterates over the words in the input string, searching for matching commands.
- Main Function:
- The
main()
function creates the command list, callstest()
with a sample input string, and then frees the command list.
In summary, this code creates a linked list of commands with their minimum lengths and provides functions to match commands to input strings. It also includes memory management and string manipulation helpers. By abstracting the command matching process, this code serves as a foundation for building command-line interpreters or other applications that need to handle user input.
Source code in the c programming language
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char* command_table =
"add 1 alter 3 backup 2 bottom 1 Cappend 2 change 1 Schange Cinsert 2 Clast 3 "
"compress 4 copy 2 count 3 Coverlay 3 cursor 3 delete 3 Cdelete 2 down 1 duplicate "
"3 xEdit 1 expand 3 extract 3 find 1 Nfind 2 Nfindup 6 NfUP 3 Cfind 2 findUP 3 fUP 2 "
"forward 2 get help 1 hexType 4 input 1 powerInput 3 join 1 split 2 spltJOIN load "
"locate 1 Clocate 2 lowerCase 3 upperCase 3 Lprefix 2 macro merge 2 modify 3 move 2 "
"msg next 1 overlay 1 parse preserve 4 purge 3 put putD query 1 quit read recover 3 "
"refresh renum 3 repeat 3 replace 1 Creplace 2 reset 3 restore 4 rgtLEFT right 2 left "
"2 save set shift 2 si sort sos stack 3 status 4 top transfer 3 type 1 up 1";
typedef struct command_tag {
char* cmd;
size_t length;
size_t min_len;
struct command_tag* next;
} command_t;
// str is assumed to be all uppercase
bool command_match(const command_t* command, const char* str) {
size_t olen = strlen(str);
return olen >= command->min_len && olen <= command->length
&& strncmp(str, command->cmd, olen) == 0;
}
// convert string to uppercase
char* uppercase(char* str, size_t n) {
for (size_t i = 0; i < n; ++i)
str[i] = toupper((unsigned char)str[i]);
return str;
}
void fatal(const char* message) {
fprintf(stderr, "%s\n", message);
exit(1);
}
void* xmalloc(size_t n) {
void* ptr = malloc(n);
if (ptr == NULL)
fatal("Out of memory");
return ptr;
}
void* xrealloc(void* p, size_t n) {
void* ptr = realloc(p, n);
if (ptr == NULL)
fatal("Out of memory");
return ptr;
}
char** split_into_words(const char* str, size_t* count) {
size_t size = 0;
size_t capacity = 16;
char** words = xmalloc(capacity * sizeof(char*));
size_t len = strlen(str);
for (size_t begin = 0; begin < len; ) {
size_t i = begin;
for (; i < len && isspace((unsigned char)str[i]); ++i) {}
begin = i;
for (; i < len && !isspace((unsigned char)str[i]); ++i) {}
size_t word_len = i - begin;
if (word_len == 0)
break;
char* word = xmalloc(word_len + 1);
memcpy(word, str + begin, word_len);
word[word_len] = 0;
begin += word_len;
if (capacity == size) {
capacity *= 2;
words = xrealloc(words, capacity * sizeof(char*));
}
words[size++] = word;
}
*count = size;
return words;
}
command_t* make_command_list(const char* table) {
command_t* cmd = NULL;
size_t count = 0;
char** words = split_into_words(table, &count);
for (size_t i = 0; i < count; ++i) {
char* word = words[i];
command_t* new_cmd = xmalloc(sizeof(command_t));
size_t word_len = strlen(word);
new_cmd->length = word_len;
new_cmd->min_len = word_len;
new_cmd->cmd = uppercase(word, word_len);
if (i + 1 < count) {
char* eptr = 0;
unsigned long min_len = strtoul(words[i + 1], &eptr, 10);
if (min_len > 0 && *eptr == 0) {
free(words[i + 1]);
new_cmd->min_len = min_len;
++i;
}
}
new_cmd->next = cmd;
cmd = new_cmd;
}
free(words);
return cmd;
}
void free_command_list(command_t* cmd) {
while (cmd != NULL) {
command_t* next = cmd->next;
free(cmd->cmd);
free(cmd);
cmd = next;
}
}
const command_t* find_command(const command_t* commands, const char* word) {
for (const command_t* cmd = commands; cmd != NULL; cmd = cmd->next) {
if (command_match(cmd, word))
return cmd;
}
return NULL;
}
void test(const command_t* commands, const char* input) {
printf(" input: %s\n", input);
printf("output:");
size_t count = 0;
char** words = split_into_words(input, &count);
for (size_t i = 0; i < count; ++i) {
char* word = words[i];
uppercase(word, strlen(word));
const command_t* cmd_ptr = find_command(commands, word);
printf(" %s", cmd_ptr ? cmd_ptr->cmd : "*error*");
free(word);
}
free(words);
printf("\n");
}
int main() {
command_t* commands = make_command_list(command_table);
const char* input = "riG rePEAT copies put mo rest types fup. 6 poweRin";
test(commands, input);
free_command_list(commands);
return 0;
}
You may also check:How to resolve the algorithm Bernoulli numbers step by step in the AppleScript programming language
You may also check:How to resolve the algorithm Floyd's triangle step by step in the D programming language
You may also check:How to resolve the algorithm Loops/Downward for step by step in the TUSCRIPT programming language
You may also check:How to resolve the algorithm Fractal tree step by step in the Red programming language
You may also check:How to resolve the algorithm Host introspection step by step in the Rust programming language