Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

3. Consider the following C codes. Finish the code in formatter.c which receives

ID: 3574745 • Letter: 3

Question

3. Consider the following C codes. Finish the code in formatter.c which receives an arrays of strings, reads formatting options and return the array where each line has the appropiate format using dinamically allocated memory(ex.c already creates a statically -­ allocated array of strings and passes this to the format_lines() function in formatter.c), add functions and change any code if neccesary. The following array of strings in ex.c contains the formatting option ".LW width", which indicates that the following text must be formatted such that each line following the command will be formatted such that there is never more than width characters in each line. Concatenates the lines of a paragraph in order to eliminate unnecessary white space. If this command does not appear in the input text, then the input text is not transformed in the output

Example:

Input:

.LW 30

Properly formatting a file where

there

            is

         a smattering of white space throughout

       really means eliminating that

                       extra

                               white

                                    space

        such that the result

looks neat

          and

                very

             tidy.

Output:

Properly formatting a file

where there is a smattering of

white space throughout really

means eliminating that extra

white space such that the

result looks neat and very

tidy.

ex.c

#include <stdio.h
#include <stdlib.h>
#include <string.h>
#include "formatter.h"

int main(int argc, char *argv[]) {
        char **result;
        char *lines[] = {
                ".LW 30",
                "While there    are enough characters   here to",
                "fill",
                "   at least one line, there is",
                "plenty",
                "of",
                "            white space that needs to be",
                "eliminated",
                "from the original",
                "         text file."
        };
        char **line;
        result = format_lines(lines, 10);
        for (line = result; *line != NULL; line++) {
                printf ("%s ", *line);
        }

        exit(0);
}

formatter.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "formatter.h"


char **format_lines(char **lines, int num_lines) {
        char **result = NULL;

        result = (char **)malloc(sizeof(char *) * 2);
        if (result == NULL) {
                return NULL;
        }

        result[0] = (char *)malloc(sizeof(char) * 80);
        if (result[0] == NULL) {
                return NULL;
        }
        strncpy(result[0], "(machine-like voice) EXTERMINATE THEM!", 79);

        result[1] = (char *)malloc(sizeof(char) * 2);
        if (result[1] == NULL) {
                return NULL;
        }
        result[1][0] = '';

        return result;
}


Explanation / Answer

//main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "formatter.h"
#include "dynamic_array.h"

int main(int argc, char *argv[]) {


DynamicArray *result = NULL;
int i = 0;
  
char *lines[] = {
"?width 30",
"While there are enough characters here to",
"fill",
" at least one line, there is",
"plenty",
"of",
" white space that needs to be",
"eliminated",
"from the original",
" text file."  
};
char **line;


result = format_lines(lines, 10);

if (result == NULL) {
printf("%s: it appears 'format_lines' is not yet complete ",
   argv[0]);
exit(1);
}

for (i = 0; i < result->length; i++){
printf("%s ", result[i]);
}
  
exit(0);
}

=====================================================================

/**
//file format_options.c
*/

#include "format_options.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>


int parse_int(char *s){
char *last;

long l = strtol(s, &last, 10);
if (last[0] != ''){
fprintf(stderr, "Error converting '%s' to integer ", s);
return -1;
}
return (int) l;
}

void ws_adjust(FormatOptions *fopt, char *arg){
int n;
if ((n = parse_int(arg)) >= 0){
fopt->word_spacing = n;
}
}

void lw_adjust(FormatOptions *fopt, char *arg){
int n;
if ((n = parse_int(arg)) > 0){
fopt->line_width = n;
}

fopt->formatting = 1;

}

void lm_adjust(FormatOptions *fopt, char *arg){
int n;
int proposed_margin;
int max_margin = fopt->line_width - 20;

if (strncmp(arg, "+", 1) == 0){
n = parse_int(arg + 1);
proposed_margin = n + fopt->left_margin;
fopt->left_margin = proposed_margin > max_margin ?
max_margin : proposed_margin;
} else if (strncmp(arg, "-", 1) == 0){
n = parse_int(arg + 1);
proposed_margin = fopt->left_margin - n;
fopt->left_margin = proposed_margin < 0 ?
0 : proposed_margin;
} else {
n = parse_int(arg);
fopt->left_margin = n;
}
}

void ft_adjust(FormatOptions *fopt, char *arg){
if (strncmp(arg, "on", 2) == 0){
fopt->formatting = 1;
} else {
fopt->formatting = 0;
}
}

void ls_adjust(FormatOptions *fopt, char *arg){
int n;
if ((n = parse_int(arg)) >= 0){
fopt->line_spacing = n;
}
}

/**
* main export function
*/
void
format_options_update(FormatOptions *fopt, char *directive, char *arg){
if (strncmp(directive, ".WS", 3) == 0){
ws_adjust(fopt, arg);
} else if (strncmp(directive, ".LW", 3) == 0){
lw_adjust(fopt, arg);
} else if (strncmp(directive, ".LM", 3) == 0){
lm_adjust(fopt, arg);
} else if (strncmp(directive, ".FT", 3) == 0){
ft_adjust(fopt, arg);
} else if (strncmp(directive, ".LS", 3) == 0){
ls_adjust(fopt, arg);
}
}

void
format_options_init(FormatOptions *fopt){
fopt->left_margin = 0;
fopt->formatting = 0;
fopt->line_spacing = 0;
fopt->word_spacing = 1;
fopt->line_width = 132;
}

==========================================================================

/**
* ile format_options.h
*/

#ifndef _FORMAT_OPTIONS_H
#define _FORMAT_OPTIONS_H

typedef struct {
int left_margin;
int line_width;
int formatting;
int line_spacing;
int word_spacing;
} FormatOptions;


void
format_options_update(FormatOptions *fopt, char *directive, char *arg);

void
format_options_init(FormatOptions *fopt);

#endif /* _FORMAT_OPTIONS_H */

=======================================================================

//dynamic_array.c

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "dynamic_array.h"

void
resize(DynamicArray *da);

void
dynamic_array_init(DynamicArray *da){
da->length = 0;
da->capacity = DA_DEFAULT_SIZE;
da->items = malloc(sizeof(char *) * DA_DEFAULT_SIZE);
}

void
dynamic_array_add(DynamicArray *da, char *word){
if (da->length >= da->capacity){
resize(da);
}

char **curr_pos = da->items + da->length;
int wordlength = strlen(word);

*(curr_pos) = malloc(sizeof(char) * (wordlength + 1));

strncpy(*(curr_pos), word, wordlength);
strncpy(*(curr_pos) + wordlength, "", 1);
  
da->length += 1;
}

void
dynamic_array_destroy(DynamicArray *da){
int i = 0;
for (i = 0; i < da->length; i++){
free(da->items[i]);
}
free(da->items);
}

void
resize(DynamicArray *da){
da->capacity = da->capacity * 2;
da->items = realloc(da->items, (sizeof(char *) * da->capacity));
if (!da->items){
fprintf(stderr, "Realloc Error ");
exit(-1);
}
}

=====================================================================

/**
* dynamic_array.h
*/

#ifndef _DYNAMIC_ARRAY_H
#define _DYNAMIC_ARRAY_H

#define DA_DEFAULT_SIZE 100

typedef struct {
int length;
int capacity;
char **items;
} DynamicArray;

void
dynamic_array_init(DynamicArray *);

void
dynamic_array_add(DynamicArray *, char *);

void
dynamic_array_destroy(DynamicArray *);

#endif /* _DYNAMIC_ARRAY_H */

======================================================================

//formatter.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "formatter.h"
#include "dynamic_array.h"
#include "output_line.h"
#include "format_options.h"


FormatOptions *
fo_copy(FormatOptions *fopt){
FormatOptions *new_fopt = malloc(sizeof(FormatOptions));
new_fopt->formatting = fopt->formatting;
new_fopt->left_margin = fopt->left_margin;
new_fopt->line_width = fopt->line_width;
new_fopt->word_spacing = fopt->word_spacing;
new_fopt->line_spacing = fopt->line_spacing;

return new_fopt;
}

int
is_command(char *word){
char *COMMANDS[5] = {".LW", ".LM", ".FT", ".LS", ".WS"};
int i = 0;
for (i = 0; i < 5; i++){
if (strncmp(COMMANDS[i], word, 3) == 0){
return 1;
}
}
return 0;
}

/**
* my main format funciton
*/
void
format(DynamicArray *input, DynamicArray *output){
int i = 0;
int j = 0;
int linelength = 0;
char *line_cpy = NULL;
int wordlength = 0;
char *word = NULL;
char *argument = NULL;
int err;

/* setup format options */
FormatOptions *fopt = malloc(sizeof(FormatOptions));
format_options_init(fopt);

/* setup output line */
OutputLine *ol = malloc(sizeof(OutputLine));
outputline_init(ol, fo_copy(fopt));

for (i = 0; i < input->length; i++){ /* for each line */
linelength = my_strlen(input->items[i]);
if (linelength == 0){
/* dump what we've got */
outputline_dump(ol, output, 0);
/* renew outputline */
outputline_init(ol, fo_copy(fopt));

/* send through the newline */
dynamic_array_add(output, "");
for (j = 0; j < ol->fopt->line_spacing; j++){
   dynamic_array_add(output, "");
}
continue;
}

/* copy in case we don't need to format */
line_cpy = malloc(sizeof(char) * (linelength + 1));
strncpy(line_cpy, input->items[i], linelength);
strncpy(line_cpy + linelength, "", 1);


/* parse this line */
word = strtok(input->items[i], " ");
wordlength = my_strlen(word);

/* empty line */
/* if (wordlength == 0){ */
/* continue; */
/* } */

/* assume nonempty line */
if (is_command(word)){
argument = strtok(NULL, " ");
format_options_update(fopt, word, argument);

/* if the output_line is empty, we should update formatting on
   the fly
*/
if (ol->char_count == 0){
   free(ol->fopt);
   outputline_init(ol, fo_copy(fopt));
}
continue;
}

/* otherwise, this is an ordinary line */
if (! ol->fopt->formatting){
/* no formatting */
dynamic_array_add(output, line_cpy);
free(line_cpy);
continue;
}

/* continue parsing the line */
do {

sscanf(word, "%s", word);
if ((err = outputline_has_room(ol, word)) > 0){
  
   /* fprintf(stderr, "adding %s of length %d ", word, my_strlen(word)); */
   /* int lk = 0; */
   /* for (lk = 0; lk < my_strlen(word); lk++){ */
   /* fprintf(stderr, "char[%d] is %c ", lk, word[lk]); */
   /* } */
   /* fprintf(stderr, " "); */
  
   outputline_add_word(ol, word);
} else if (err < 0){
   exit(-1);
} else {
   /* gotta dump line */
   outputline_dump(ol, output, 0);

   free(ol->fopt);
   outputline_init(ol, fo_copy(fopt));
   /* now we can add */
   outputline_add_word(ol, word);
}

word = strtok(NULL, " ");
} while (word);

}
outputline_dump(ol, output, 1);
}

char *
my_getline(FILE *f){
DynamicArray *da = malloc(sizeof(DynamicArray));
dynamic_array_init(da);
char c[] = {' ', ''};
int i = 0;
char *return_line;
  
while ((c[0] = fgetc(f)) != EOF){
if (c[0] == ' '){
break;
}
dynamic_array_add(da, c);
}

if (c[0] != EOF){
return_line = malloc(sizeof(char) * (da->length + 1));
  
for (i = 0; i < da->length; i++){
strncpy(return_line + i, da->items[i], 1);
}

return_line[da->length] = '';


dynamic_array_destroy(da);
}
  
if (c[0] != EOF){
return return_line;
}

return NULL;

}

void
read_file_in(FILE *infile, DynamicArray *da){
/* char *lineptr = NULL; */
/* size_t n = 0; */
/* int num_chars = 0; */
/* while ((num_chars = getline(&lineptr, &n, infile)) != -1){ */
/* /* kill newline */ */
/* lineptr[num_chars - 1] = ''; */
/* dynamic_array_add(da, lineptr); */
/* } */
/* free(lineptr); */

char *this_line = my_getline(infile);
  
while (this_line){
dynamic_array_add(da, this_line);
free(this_line);
this_line = my_getline(infile);
}
}

DynamicArray *
format_stdin(){
DynamicArray *input;
DynamicArray *output;
input = malloc(sizeof(DynamicArray));
dynamic_array_init(input);

read_file_in(stdin, input);

output = malloc(sizeof(DynamicArray));
dynamic_array_init(output);
format(input, output);

return output;
}

DynamicArray *
format_file(FILE *infile) {
DynamicArray *input;
DynamicArray *output;
input = malloc(sizeof(DynamicArray));
dynamic_array_init(input);

/* read the input file into the input array*/
read_file_in(infile, input);

output = malloc(sizeof(DynamicArray));
dynamic_array_init(output);
format(input, output);

dynamic_array_destroy(input);
return output;
}


DynamicArray *
format_lines(char **lines, int num_lines) {
int i = 0;
DynamicArray *input;
DynamicArray *output;

input = malloc(sizeof(DynamicArray));
dynamic_array_init(input);
for (i = 0; i < num_lines; i++){
dynamic_array_add(input, lines[i]);
}

output = malloc(sizeof(DynamicArray));
format(input, output);

dynamic_array_destroy(input);
return output;
}

==================================================================

//formatter.h

#ifndef _FORMATTER_H_
#define _FORMATTER_H_

#include <stdio.h>

#include "dynamic_array.h"

DynamicArray *format_file(FILE *);
DynamicArray *format_lines(char **, int);
DynamicArray *format_stdin(void);

#ifdef DBG_FORMAT

void
format(DynamicArray *input, DynamicArray *output);

void
read_stdin(DynamicArray *da);

void
read_file_in(FILE *infile, DynamicArray *da);

#endif   /* DBG_FORMAT */

#endif   /* _FORMATTER_H_ */

================================================================

//output_line.c

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "output_line.h"
#include "dynamic_array.h"
#include "format_options.h"

int
my_strlen(char *s){
int count = 0;
if (s[0] == 'â'){
return 1;
}
for (count = 0; s[count] != ''; count++);


return count;
}


void
outputline_init(OutputLine *ol, FormatOptions *fopt){
int i = 0;
ol->fopt = fopt;        /* should already by init'ed */
ol->words = malloc(sizeof(DynamicArray));
dynamic_array_init(ol->words);
ol->char_count = 0;
ol->space_holder = malloc(sizeof(char) * (fopt->word_spacing + 1));
for (i = 0; i < fopt->word_spacing; i++){
ol->space_holder[i] = ' ';
}
ol->space_holder[fopt->word_spacing] = '';
}

void
outputline_add_word(OutputLine *ol, char *word){
int wordlength = my_strlen(word);

if (wordlength < 1){
return;
}

if (ol->words->length == 0){    /* we're empty */
ol->char_count += wordlength;
} else {
ol->char_count += wordlength + ol->fopt->word_spacing;
}

dynamic_array_add(ol->words, word);
}

int
outputline_has_room(OutputLine *ol, char *word){
int wordlength = my_strlen(word);
if (wordlength > ol->fopt->line_width - ol->fopt->left_margin){
fprintf(stderr, "Word too long: %s ", word);
fprintf(stderr, "line_width - left_margin = %d - %d and wordlength is %d ",
   ol->fopt->line_width, ol->fopt->left_margin, wordlength);

return -1;
}
if (ol->words->length == 0){ /** current line is empty */
return ol->fopt->line_width - ol->fopt->left_margin - wordlength >= 0;
} else { /* need to account for space */
return ol->fopt->line_width - ol->fopt->word_spacing -
wordlength - ol->fopt->left_margin - ol->char_count >= 0;
}
}

void
outputline_dump(OutputLine *ol, DynamicArray *dest, int is_lastline){
int out_line_length = 0;
char *out_line = NULL;
int i = 0;
int cursor = 0;        /* position we're writing to */
int num_words = 0;

if (ol->words->length == 0){
return;
}

/* get the length of each word */
for (i = 0; i < ol->words->length; i++){
out_line_length += strlen(ol->words->items[i]);
}
/* add whitespace in between to length */
out_line_length += (ol->words->length - 1) * ol->fopt->word_spacing;

/* add margin to length */
out_line_length += ol->fopt->left_margin;

if (! is_lastline){
/* add newlines to length */
out_line_length += ol->fopt->line_spacing;
}

/* create a new line */
out_line = malloc(sizeof(char) * (out_line_length + 1));

/* copy margin */
for (i = 0; i < ol->fopt->left_margin; i++){
strncpy(out_line + i, " ", 1);
}
cursor += ol->fopt->left_margin;

/* copy into the line */
num_words = ol->words->length;
for (i = 0; i < num_words - 1; i++){
strncpy(out_line + cursor, ol->words->items[i], strlen(ol->words->items[i]));
cursor += strlen(ol->words->items[i]);

strncpy(out_line + cursor, ol->space_holder, ol->fopt->word_spacing);
cursor += ol->fopt->word_spacing;

}
/* get the last word, no space after */
strncpy(out_line + cursor, ol->words->items[num_words - 1],
   strlen(ol->words->items[num_words - 1]));

cursor += strlen(ol->words->items[num_words - 1]);

/* add newlines */
if (! is_lastline){
for (i = 0; i < ol->fopt->line_spacing; i++){
strncpy(out_line + cursor, " ", 1);
cursor += 1;
}
}

/* cap this line */
strncpy(out_line + cursor, "", 1);
cursor += 1;

/* add it to the dynamic array */
dynamic_array_add(dest, out_line);

/* now we have to purge the output_line, and free out_line */
dynamic_array_destroy(ol->words);
dynamic_array_init(ol->words);

free(out_line);

}

=====================================================================

//output_line.h

#ifndef _OUTPUT_LINE_H
#define _OUTPUT_LINE_H

/**
* output_line class
*/

#include "format_options.h"
#include "dynamic_array.h"

typedef struct {
FormatOptions *fopt;
DynamicArray *words;
int char_count;
char *space_holder;
} OutputLine;

void
outputline_init(OutputLine *ol, FormatOptions *fopt);

void
outputline_add_word(OutputLine *ol, char *word);

int
outputline_has_room(OutputLine *ol, char *word);

/**
* pops the current line into the dynamic array
*/
void
outputline_dump(OutputLine *ol, DynamicArray *dest, int is_lastline);

#endif /* _OUTPUT_LINE_H */

==============================================================================

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote