I'm very new to C and programing in general and I'm currently trying to write a program that will word-wrap a paragraph of text so that no line in the text is longer than a certain size. The readfile function reads the lines of text from the text file and put it into array of strings called text where each element of the text array is a line in the text and the write code that creates a new array of strings called newtext where each element of the array is a word-wrapped line limited to a length specified by the linewidth variable. My current issue is that my code seems to be generating an output that is slightly off the expected output and I'm not certain why.
Here is the expected output:

I've tried adjusting the end index and writing a separate loop for skipping empty spaces and nothing seems to fix this particular error
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int readfile(char* filename, char*** bufp)
{
FILE* fp = fopen(filename, "r");
char** buf = NULL;
int numlines = 0;
char tmp[1000];
while (fgets(tmp, sizeof(tmp), fp)) {
if (numlines % 16 == 0) {
buf = (char**)realloc(buf, (numlines+16) * sizeof(char*));
}
int len = strlen(tmp);
tmp[len-1] = 0;
buf[numlines] = malloc(len + 1);
strcpy(buf[numlines], tmp);
numlines++;
}
*bufp = buf;
return numlines;
}
void print_text(char** lines, int numlines) {
for (int i=0; i<numlines; i++) {
printf("%s\n", lines[i]);
}
}
int main(int argc, char** argv) {
char** text;
int numlines = readfile(argv[1], &text);
int linewidth = atoi(argv[2]);
char** newtext = NULL;
int newnumlines = 0;
// TODO
// iterate through the text array
// create a char* variable line = text[i]
// iterate through the line
// if you are starting a new line allocate space for the newline
// make sure you put the newline into the newtext array
// and check if you need to reallocate the newtext array
//
// copy the character into the newline array
// check if you have reached the max linewidth
// if you aren't already at the end of a word,
// backtrack till we find a space or get to start of line
// terminate the newline and reset the newline position to 0
// put a space in the newline, unless you are at the end of the newline
for (int i = 0; i < numlines; i++)
{
char * line = text[i];
int length = strlen(line);
int x = 0;
int start = 0;
while (start < length) {
// Calculate the end index of the current line segment
int end = start + linewidth;
// Adjust the end index if it falls within a word
while (end > start && end < length && line[end] != ' ') {
end--;
}
char *newline = malloc(end - x + 1 + 1);
strncpy(newline, line + start, end - start);
newline[end - start] = '\0';
newtext = realloc(newtext, (newnumlines + 1) * sizeof(char*));
newtext[newnumlines++] = newline;
start = end;
while(start < length && line[start] == ' ')
{
start++;
}
//x = end + 1;
// start = x;
}
}
for(int i = 0; i < newnumlines; i++) {
// Skip printing empty lines
if (strlen(newtext[i]) > 0) {
printf("%s\n", newtext[i]);
}
}
//freeing memory
for(int i = 0; i < numlines; i++){
free(text[i]);
}
free(text);
for(int i = 0; i < newnumlines; i++){
free(newtext[i]);
}
free(newtext);
return 0;
}

Here is some wordwrap code that works nicely, and adheres to the rules mentioned in my comments to your question:
1.) Uses one continuous, single dimension array of text so that nothing but the end of the array will interrupt a paragraph.
2.) Ignores/strips all the existing newlines ('\n') in the source text/array. EDIT: per comments from user Fe2O3, updated code to translate newlines to spaces.
3.) Calls
next_break()to do a 'lookahead' from the current offset to anticipate if the next natural break (a space, period, etc) comes before or after the wrap margin we intend to enforce.Runnable, tested code is here. https://godbolt.org/z/hvY19Tq7x