Skip to content
Snippets Groups Projects
Commit 0a237cbc authored by Ansh's avatar Ansh
Browse files

assignment 1 done, i'm so tired

parent 6bcca68d
Branches
No related tags found
No related merge requests found
File added
......@@ -12,12 +12,71 @@ int setup_buff(char *, char *, int);
//prototypes for functions to handle required functionality
int count_words(char *, int, int);
//add additional prototypes here
//add additional prototypes here
void word_print(char *buff, int len);
void reverse_print(char *buff, int len);
int setup_buff(char *buff, char *user_str, int len){
//TODO: #4: Implement the setup buff as per the directions
return 0; //for now just so the code compiles.
// Calculate the length of the string the user put into the program
int user_str_length = 0;
char *temp_str = user_str;
// Iterate through the string to find the null terminator so we can see how long the string is
while (*temp_str != '\0') {
user_str_length++;
temp_str++;
}
// Return an error code if the inputted string is bigger than the buffer size
if (user_str_length > len) {
fprintf(stderr, "The input string you gave is too long\n");
return(-1);
}
// Initialize pointers
char *buff_ptr = buff;
char *user_str_ptr = user_str;
int consec_spaces = 0;
// Go through the string and copy the characters to the buffer
while (*user_str_ptr != '\0') {
char current_char = *user_str_ptr;
// Check to see if the current character is a space or a tab
if (current_char == ' ' || current_char == '\t') {
// This will add a single space if it's not a consecutive whitespace
if (!consec_spaces && buff_ptr != buff) {
*buff_ptr = ' ';
buff_ptr++;
}
// Set the flag for the consecutive spaces
consec_spaces = 1;
}
// Copy the character to the buffer, move the buffer pointer to the next position, and reset the consecutive space flag
else {
*buff_ptr = current_char;
buff_ptr++;
consec_spaces = 0;
}
// Move to the next character in the user string
user_str_ptr++;
}
// Fill the remaining buffer spaces with .
while (buff_ptr < buff + len) {
*buff_ptr = '.';
buff_ptr++;
}
// Return the length of the user string
return user_str_length;
}
void print_buff(char *buff, int len){
......@@ -34,12 +93,117 @@ void usage(char *exename){
}
int count_words(char *buff, int len, int str_len){
//YOU MUST IMPLEMENT
return 0;
// Check to make sure the user string is larger than the buffer size
if (str_len > len) {
printf("User input is larger than the buffer size.\n");
return -3;
}
// Initialize counters for words and a flag to tell if we're in a word
int word_count = 0;
int in_a_word = 0;
// Iterate through the buffer until we reach the end of the user string
for (int i = 0; i < str_len; i++) {
// Get the currect character from the buffer
char current_char = *(buff + i);
// Check if the current character is a space or tab
if (current_char == ' ' || current_char == '\t') {
// Reset in a word flag if it's a space or tab
in_a_word = 0;
}
else {
// If we weren't in a word and we see a non-whitespace character, start a new word and increment the word count
if (in_a_word == 0) {
word_count++;
}
// Set the flag to indicate we are inside a word
in_a_word = 1;
}
}
// Print the final word count and return the word count
printf("Word Count: %d\n", word_count);
return word_count;
}
//ADD OTHER HELPER FUNCTIONS HERE FOR OTHER REQUIRED PROGRAM OPTIONS
void word_print(char *buff, int len) {
// Initial prints to set up the format
printf("Word Print\n");
printf("----------\n");
// Initialize variables and pointers for the start of the current word, length of the current word, and the count for the number of words
char *start_of_word = NULL;
int word_length = 0;
int word_count = 1;
// Iterate over each character in the buffer
for (int i = 0; i < len; i++) {
// Check if the current character is actually a character
if(*(buff + i) != ' ' && *(buff + i) != '.' && *(buff + i) != '\0') {
// Mark the start of the word
if (start_of_word == NULL) {
start_of_word = buff + i;
}
// Increment the word length because we're inside a word
word_length++;
}
// If we encounter non-character and we're currently inside of a word
else if (start_of_word != NULL) {
// Print the word count and the word itself
printf("%d. ", word_count++);
// Print the characters of the current word
for (int j = 0; j < word_length; j++) {
printf("%c", *(start_of_word + j));
}
// Print the length of the word
printf(" (%d)\n", word_length);
// Reset for the next word
start_of_word = NULL;
word_length = 0;
}
}
// If the loop ends and there's still a word being processed, print the word
if (start_of_word != NULL) {
printf("%d. ", word_count);
for (int j = 0; j < word_length; j++) {
printf("%c", *(start_of_word + j));
}
printf(" (%d)\n", word_length);
}
}
void reverse_print(char *buff, int len) {
// Give an error message if the buffer length is 0 (there's no word)
if (len == 0) {
printf("Error: The string you put in is empty and we can't reverse it\n");
exit(3);
}
// Initial print to setup the format
printf("Reversed String: ");
// Loop through the buffer starting from the last character moving backwards and printing it so it prints in reverse
for (int i = len - 1; i >= 0; i--) {
printf("%c", *(buff + i));
}
// Prints a new line after reversing
printf("\n");
}
int main(int argc, char *argv[]){
char *buff; //placehoder for the internal buffer
......@@ -50,6 +214,15 @@ int main(int argc, char *argv[]){
//TODO: #1. WHY IS THIS SAFE, aka what if arv[1] does not exist?
// PLACE A COMMENT BLOCK HERE EXPLAINING
/*
* The reason that this if statement is safe is because it checks to see how many command line arguments there are before trying to access them.
* If there are less than 2 command line arguments, that means that the command is incomplete, so when we go to access it, there might be unintended behavior that we may not have accounted for.
* Since the program checks before accessing it, it will exit the command before we even try to use it, so that unintended behavior will never happen.
* If there are 2 or more arguments though, it will make sure that the 2nd command line input has a - in it, as that is what is used to call the different functions.
* If it doesn't, it will follow the same fate as if you don't have 2 or more command line arguments.
* It will exit the program with a command line failure code.
*/
if ((argc < 2) || (*argv[1] != '-')){
usage(argv[0]);
exit(1);
......@@ -67,6 +240,11 @@ int main(int argc, char *argv[]){
//TODO: #2 Document the purpose of the if statement below
// PLACE A COMMENT BLOCK HERE EXPLAINING
/*
* This is the same thing as the previous TODO if statement, except this will run after the first check already happens.
* If there are 2 or more command line arguments, and the 2nd one has a - in it, then it will check to see if there are 3 command line arguments.
* This check is to make sure taht there is a sample string passed along. If there isn't, it will exit with code 1 to indicate a command line error.
*/
if (argc < 3){
usage(argv[0]);
exit(1);
......@@ -78,7 +256,15 @@ int main(int argc, char *argv[]){
// handle error if malloc fails by exiting with a
// return code of 99
// CODE GOES HERE FOR #3
buff = (char *)malloc(BUFFER_SZ);
// Check to make sure the malloc worked properly
if(buff == NULL) {
fprintf(stderr, "Memory allocation failure\n");
exit(99);
}
user_str_len = setup_buff(buff, input_string, BUFFER_SZ); //see todos
if (user_str_len < 0){
......@@ -98,13 +284,30 @@ int main(int argc, char *argv[]){
//TODO: #5 Implement the other cases for 'r' and 'w' by extending
// the case statement options
// Call reverse_print when user inputs -r
case 'r':
reverse_print(buff, user_str_len);
break;
// Call word_print when user inputs -w
case 'w':
word_print(buff, user_str_len);
break;
default:
usage(argv[0]);
exit(1);
}
//TODO: #6 Dont forget to free your buffer before exiting
// Print the entire buffer after a user inputs the command line argument call
print_buff(buff,BUFFER_SZ);
// Free memory
free(buff);
exit(0);
}
......@@ -114,4 +317,11 @@ int main(int argc, char *argv[]){
// is a good practice, after all we know from main() that
// the buff variable will have exactly 50 bytes?
//
// PLACE YOUR ANSWER HERE
\ No newline at end of file
// PLACE YOUR ANSWER HERE
//
/*
* Since we are giving the functions both the buffer and the length of it, it lets us have it just incase we need it for error preventions.
* You could use the length of the buffer to double check that the length of the user string is still within range of the buffer, just incase anything happened to it from when we first checked it to the function.
* For example, if we decide to change the buffer size to something more flexible, it will be sent out to all the functions to again, check to make sure that it still fits.
*/
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment