Skip to content
Snippets Groups Projects
Commit 6883e1b1 authored by bgm47's avatar bgm47 :boy_tone1:
Browse files

update assignment 1

parent 70031efb
Branches
No related tags found
No related merge requests found
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SZ 50
//prototypes
void usage(char *);
void print_buff(char *, int);
int setup_buff(char *, char *, int);
int count_words(char *, int, int);
void reverse(char *, int, int);
void printw(char *, int, int);
void srplace(char *, int, char *, char *, int);
//prototypes for functions to handle required functionality
int count_words(char *buff, int len, int str_len) {
int word_count = 0;
int in_word = 0;
for (int i = 0; i < str_len; i++) {
if (*(buff + i) != ' ') {
if (!in_word) {
in_word = 1;
word_count++;
}
} else {
in_word = 0;
}
}
return word_count;
}
int setup_buff(char *buff, char *user_str, int len) {
char *src = user_str;
char *dest = buff;
int count = 0;
int space_flag = 0;
while (*src != '\0' && count < len) {
if (*src == ' ' || *src == '\t') {
if (!space_flag) {
*dest++ = ' ';
count++;
space_flag = 1;
}
} else {
*dest++ = *src;
count++;
space_flag = 0;
}
src++;
}
if (*src != '\0') {
return -1;
}
while (count < len) {
*dest++ = '.';
count++;
}
return count;
}
void print_buff(char *buff, int len) {
printf("Buffer: [");
for (int i = 0; i < len; i++) {
putchar(*(buff + i));
}
printf("]\n");
}
void usage(char *exename) {
printf("usage: %s [-h|c|r|w|x] \"string\" [other args]\n", exename);
}
void reverse(char *buff, int len, int str_len) {
char *start = buff;
char *end = buff + str_len - 1;
char temp;
while (start < end) {
temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
}
void printw(char *buff, int len, int str_len) {
int word_index = 1;
int word_length = 0;
printf("Word Print\n----------\n");
for (int i = 0; i < str_len; i++) {
char current_char = *(buff + i);
if ((current_char >= 'A' && current_char <= 'Z') ||
(current_char >= 'a' && current_char <= 'z') ||
(current_char >= '0' && current_char <= '9')) {
if (word_length == 0) {
printf("%d. ", word_index);
}
putchar(current_char);
word_length++;
} else if (current_char == ' ' && word_length > 0) {
printf("(%d)\n", word_length);
word_index++;
word_length = 0;
}
}
if (word_length > 0) {
printf(" (%d)\n", word_length);
}
printf("\nNumber of words returned: %d\n", word_index);
}
void srplace(char *buff, int len, char *old, char *new, int str_len) {
char temp[BUFFER_SZ];
char *src = buff, *dest = temp;
int old_len = strlen(old), new_len = strlen(new);
int replaced = 0;
while (*src != '\0' && (dest - temp) < BUFFER_SZ) {
if (strncmp(src, old, old_len) == 0) {
if ((dest - temp) + new_len > BUFFER_SZ) {
break; // Prevent overflow
}
strncpy(dest, new, new_len);
src += old_len;
dest += new_len;
replaced = 1;
} else {
*dest++ = *src++;
}
}
while ((dest - temp) < BUFFER_SZ) {
*dest++ = '.';
}
if (replaced) {
memcpy(buff, temp, BUFFER_SZ);
} else {
printf("Not Implemented!\n");
exit(1);
}
}
int main(int argc, char *argv[]) {
char *buff; //placehoder for the internal buffer
char *input_string; //holds the string provided by the user on cmd line
char opt; //used to capture user option from cmd line
int rc; //used for return codes
int user_str_len; //length of user supplied string
//TODO: #1. WHY IS THIS SAFE, aka what if arv[1] does not exist?
//This is done to make that the command has the right syntax and all the minimal arguments
//needed for the subsequent operations to run with valid inputs, or to specify the type of error
//so the user may rectify it and find the right command that will work.
if ((argc < 2) || (*argv[1] != '-')){
usage(argv[0]);
exit(1);
}
opt = (char)*(argv[1]+1);
//handle the help flag and then exit normally
if (opt == 'h'){
usage(argv[0]);
exit(0);
}
//WE NOW WILL HANDLE THE REQUIRED OPERATIONS
//TODO: #2 Document the purpose of the if statement below
//It ensures that the user enters a command with at least one flag and two required parameters
//to proceed. Otherwise, an error will occur, and the syntax will assist them enter the right command.
if (argc < 3){
usage(argv[0]);
exit(1);
}
input_string = argv[2]; //capture the user input string
//TODO: #3 Allocate space for the buffer using malloc and
// handle error if malloc fails by exiting with a
// return code of 99
buff = (char *)malloc(BUFFER_SZ);
if (buff == NULL) {
exit(99);
}
user_str_len = setup_buff(buff, input_string, BUFFER_SZ);
if (user_str_len < 0) {
printf("Error setting up buffer\n");
free(buff);
exit(2);
}
switch (opt) {
case 'c':
rc = count_words(buff, BUFFER_SZ, user_str_len); //you need to implement
if (rc < 0){
printf("Error counting words, rc = %d", rc);
exit(2);
}
printf("Word Count: %d\n", rc);
break;
case 'r':
reverse(buff, BUFFER_SZ, user_str_len);
break;
case 'w':
printw(buff, BUFFER_SZ, user_str_len);
break;
case 'x':
if (argc < 5) {
usage(argv[0]);
free(buff);
exit(1);
}
srplace(buff, BUFFER_SZ, argv[3], argv[4], user_str_len);
break;
default:
usage(argv[0]);
free(buff);
exit(1);
}
//TODO: #6 Dont forget to free your buffer before exiting
print_buff(buff, BUFFER_SZ);
free(buff);
exit(0);
}
//TODO: #7 Notice all of the helper functions provided in the
// starter take both the buffer as well as the length. Why
// do you think providing both the pointer and the length
// is a good practice, after all we know from main() that
// the buff variable will have exactly 50 bytes?
//
// Both the pointer and the length must be provided since this
// will enable the function to monitor the buffer's length during and after each
// modification step to prevent overflow and to set up the buffer once the string
// operation is finished (ensuring that it always contains exactly 50 bytes).
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment