Justifying text in C and general array -
i'm attempting justify (left , right columns line-up) input files , came with. input files have embedded commands pseudo output below start justifying @ company's
line , end @ telephone
can see randomly joins 2 of lines read together. can please tell me why it's doing this? input files have newline characters in them since double checked entered.
also how do following: check if read line fit output array (of 40 char)? if doesn't want move overflowed string(s) next line or char(s) if it's easier. 1 isn't necessary first question make output nice possible , don't know how restrict , carry overflow read lines next output array.
since began escape at&t's bell laboratories in 1970's, success of unix operating system has led many different versions: recipients of (at time free) unix system code began developing own different versions in own different ways use , sale. universities, research institutes, government bodies , computer companies began using powerful unix system develop many of technologies today part of unix system. computer aided design, manufacturing control systems,laboratorysimulations,even internet itself, began life , because of unix today, without unix systems, internewould come screeching halt. telephone calls not made, electronic commerce grind halt , there have never been "jurassic park"!
below justify function that's passed read file line using fgets
in function. printf
lines debugging.
void justify(char strin[]){ int = 0; //strin iterator int j = 0; //out iterator int endspaces = line + 1 - strlen(strin); int voids = countwords(strin) - 1; printf("voids: %d\n", voids); printf("input: %s", strin); //no words in line, exit if (voids <= 0) return; //how many add between words int addevenly = endspaces/voids; int addunevenly = endspaces % voids; printf("space distribute: %d evenly: %d unevenly: %d\n", endspaces, addevenly, addunevenly); //copy space left of array output while (strin[i] == ' '){ outline[j++] = ' '; i++; } //one word @ time while (endspaces > 0 || addunevenly > 0){ //copy letters out while (strin[i] != ' '){ outline[j] = strin[i]; i++; j++; } //add necessary spaces between words if (addevenly > 0){ (int k = 0; k < addevenly; k++){ outline[j++] = ' '; } } //distribute left if (addunevenly > 0){ outline[j++] = ' '; endspaces--; addunevenly--; } printf("output: %s\n\n", outline); endspaces = endspaces - addevenly; //finish copying rest of input output when no more spaces add if (endspaces == 0 && addunevenly == 0){ while (strin[i] != '\0') outline[j++] = strin[i++]; printf("output 2: %s\n", outline); } } fprintf(out, "%s", outline); }
on sunday created function (justifyline()
) able justify , indent line give input. outputs buffer containing justified (formatted) text , eventual text-remainder; such remainder may used input function justifyline()
.
after step i've used file below (text.txt) test behaviour of such function. test demonstrates me need use word wrapping between lines. i've written function formatlinebyline()
. function formatlinebyline()
doesn't care of void lines.
text file (text.txt): (i used text in question trying correct it, not i've corrected, input file suffers of fact!)
since began escape at&t's bell laboratories in 1970's, success of unix operating system has led many different versions: recipients of (at time free) unix system code began developing own different versions in own different ways use , sale. universities, research institutes, government bodies , computer companies began using powerful unix system develop many of technologies today part of unix system. computer aided design, manufacturing control systems, laboratory simulations, internet itself, began life , because of unix today, without unix systems, internet come screeching halt. telephone calls not made, electronic commerce grind halt , there have never been "jurassic park"!
the output of function formatlinebyline()
abcde12345678901234567890123456789012345 since began escape at&t's bell laboratories in 1970's, success of unix operating system has led many different versions: recipients of (at time free) unix system code began developing own different versions in own different ways use , sale. universities, research institutes, government bodies , computer companies began using powerful unix system develop many of technologies today part of unix system. computer aided design, manufacturing control systems, laboratory simulations, internet itself, began life , because of unix today, without unix systems, internet come screeching halt. telephone calls not made, electronic commerce grind halt , there have never been "jurassic park"!
another step idea use paragraph per paragraph justifycation. i've written function justifyparagraph()
. function formatinparagraphs()
reads file text.txt , prints justified using function justifyparagraph()
.
the output of function formatinparagraphs()
abcde12345678901234567890123456789012345 since began escape at&t's bell laboratories in 1970's, success of unix operating system has led many different versions: recipients of (at time free) unix system code began developing own different versions in own different ways use , sale. universities, research institutes, government bodies , computer companies began using powerful unix system develop many of technologies today part of unix system. computer aided design, manufacturing control systems, laboratory simulations, internet itself, began life , because of unix today, without unix systems, internet come screeching halt. telephone calls not made, electronic commerce grind halt , there have never been "jurassic park"!
the function justifyline()
able create justified buffer indentation (parameter size_t indent
) , use single space between words (parameter int nospacing
sent 1).
the function justifyparagraph()
able create justified buffer line indentation (parameter: size_t indent
) , 1st line indentation (parameter: size_t indentstart
). formatted output may directly printed when null output buffer sent function (parameter char **outbuf
sent null). last line function generates may justified or not (parameter: int notfrmtlast
sent 1).
both justification functions, when parameter char **outbuf
points null pointer ( *outbuf == null ), allocate memory using malloc()
. in case have free buffer after use. if parameter passed null function justifyparagraph()
, function prints elaborated output, if outbuf
passed null function justifyline()
, function returns error.
the code below. issue of code that, in cases, length of string should computed using function different strlen()
. avoid problem may use these functions lines have single space between words. such problem affects functions justifyparagraph()
, formatlinebyline()
.
#include <stdio.h> #include <stdlib.h> #include <string.h> int justifyline(char *inbuf, char **outbuf, size_t linelen, char ** endptr, size_t indent, int nospacing); int justifyparagraph(char *inbuf,char **outbuf,size_t linelen,size_t indentstart,size_t indent,int notfmtlast); int formatlinebyline(file *f, size_t linelen,size_t indent, int notfrmtlast); int formatinparagraphs(file *f, size_t linelen,size_t indentstart,size_t indent, int notfrmtlast); int justifyparagraph(char *inbuf,char **outbuf,size_t linelen,size_t indentstart,size_t indent,int notfmtlast) { char *optr=null,*endp=null; size_t len,s; int retval,nf; for(;;) { //error control loop if (inbuf==null) { retval=0x10;break; } if (indent+indentstart>linelen) { retval=0x20;break; } if (outbuf!=null) { if (*outbuf==null) { if ( (*outbuf=malloc(linelen+1))==null ){ retval=0x30;break; } } optr=*outbuf; } endp=inbuf; indent+=indentstart; len=linelen-indent; s=indentstart;nf=0; while( *endp!=0) { if (notfmtlast && strlen(endp)<linelen-indent) nf=1; if ( (retval=justifyline(endp,&optr,linelen,&endp, indent,nf)) ) { retval|=0x40;break; } if (outbuf!=null) { optr+=strlen(optr); *optr++='\n'; *optr=0; } else { puts(optr); } indent-=s; len+=s; s=0; } break; //close error ctrl loop! } if (outbuf==null && optr!=null) free(optr); return retval; } int justifyline(char *inbuf,char **outbuf,size_t linelen, char ** endptr,size_t indent,int nospacing) { size_t textlen,tmp; size_t spctoadd,spcodd,spcin; size_t timetoodd; size_t ibidx,obidx,k,wc; char * endp; char * outb=null; int retval=0; for(;;) { //error control loop endp=inbuf; if (inbuf==null) { retval=1;break; } if (indent>linelen) { retval=2;break; } if (outbuf==null) { retval=3;break; } if (*outbuf==null) { if ( (*outbuf=malloc(linelen+1))==null ){ retval=4;break; } } outb=*outbuf; //leave right spaces while(*inbuf==' ') inbuf++; if (*inbuf==0) { endp=inbuf; *outb=0; break; //exit error loop without error! } linelen-=indent; //count words , minimum number of characters ibidx=0; wc=0;textlen=0;k=1;endp=null; while ( *(inbuf+ibidx)!=0 ) { if (*(inbuf+ibidx)==' ') { ibidx++;continue; } //there's char! k=ibidx; //last word start tmp=textlen; wc++;textlen++; //add space after words //textlen<linelen because textlen contains space after word // while(textlen<=linelen && *(inbuf+ibidx)!=' ' && *(inbuf+ibidx) ) { while(*(inbuf+ibidx)!=' ' && *(inbuf+ibidx) ) { textlen++;ibidx++; } if (textlen>linelen+1) { endp=inbuf+k; textlen=tmp; wc--; break; } } textlen=textlen-wc; if (endp==null) { endp=inbuf+ibidx; } if (textlen<2) { *outb=0; break; //exit error loop without error! } //prepare outbuf memset(outb,' ',linelen+indent); *(outb+linelen+indent)=0; ibidx=0; obidx=indent; if (wc>1) { if (!nospacing) { //the odds max in number == wc-2 spctoadd=linelen-textlen; } else { spctoadd=wc-1; } spcin=spctoadd/(wc-1); spcodd=spctoadd % (wc-1); if (spcodd) timetoodd=(wc-1)/spcodd; k=timetoodd; while(spctoadd) { while(*(inbuf+ibidx)!=' ') { *(outb+obidx++)=*(inbuf+ibidx++); } obidx+=spcin;spctoadd-=spcin; if (spcodd && !(--k)) { k=timetoodd; spcodd--; spctoadd--; obidx++; } while(*(inbuf+ ++ibidx)==' '); } } while(*(outb+obidx) && *(inbuf+ibidx) && *(inbuf+ibidx)!=' ') *(outb+obidx++)=*(inbuf+ibidx++); //there're words longer line!!! if (*(inbuf+ibidx) && *(inbuf+ibidx)!=' ') endp=inbuf+ibidx; break; //terminate error ctrl loop. } if (endptr!=null) *endptr=endp; return retval; } int formatlinebyline(file *f, size_t linelen,size_t indent, int notfrmtlast) { char text[250],*app; //justifyline allocates memory line if outbuf (optr) value null char * optr=null; size_t j,k; //print ruler for(j=0;j<indent;j++) printf("%c",'a'+(char)j); for(j=1;j<=linelen-indent;j++) printf("%c",'0'+(char)(j%10)); printf("\n"); //starts printing fseek(f,0,seek_set); j=0; while(fgets(text+j,sizeof(text)-j,f)) { if ( (app=strrchr(text+j,'\n')) ) { *app=0; } k=strlen(text); if (strlen(text)<linelen-indent) { if (!*(text+k) && *(text+k-1)!=' ') { *(text+k++)=' '; *(text+k)=0; } j=k; continue; } app=text; { //justifyline allocates memory line if outbuf (optr) value null if ( justifyline(app,&optr,linelen,&app,indent,0) ) { if (optr!=null) free(optr); return 1; } printf("%s\n",optr); j=(*app!=0)?strlen(app):0; } while(j>linelen-indent); if (j) { strcpy(text,app); *(text+j++)=' '; *(text+j)=0; } } if (*text!=0 && j) { if ( justifyline(text,&optr,linelen,null,indent,notfrmtlast) ) { if (optr!=null) free(optr); return 2; } printf("%s\n",optr); } //justifyline allocates memory line if outbuf value null if (optr!=null) free(optr); return 0; } int formatinparagraphs(file *f, size_t linelen,size_t indentstart,size_t indent, int notfrmtlast) { char text[1024], *app; //to uncomment when use commented justifyparagraph line. //see below //char *outbuf=null; size_t j; //print ruler for(j=0;j<indent;j++) printf("%c",'a'+(char)j); for(j=1;j<=linelen-indent;j++) printf("%c",'0'+(char)(j%10)); printf("\n"); //starts printing fseek(f,0,seek_set); j=0; while(fgets(text+j,sizeof(text),f)) { if ( (app=strrchr(text+j,'\n')) ) { *app++=' ';*app=0; } if ( *(text+j)==' ' && !*(text+j+1) ) { //the following commented line allocates memory creating paragraph buffer! //doesn't print formatted line. //justifyparagraph(text,&outbuf,linelen,indentstart,indent,notfrmtlast); //this line directly print buffer allocating , de-allocating //only line buffer. prints formatted line. justifyparagraph(text,null,linelen,indentstart,indent,notfrmtlast); j=0; //to uncomment when use commented justifyparagraph line. // printf("%s\n\n",outbuf); puts(""); } else { j+=strlen(text+j); } } return 0; } int main(void) { file * file; file=fopen("text.txt","r"); formatlinebyline(file,40,5,1); puts(""); formatinparagraphs(file,40,5,5,1); fclose(file); return 0; }
Comments
Post a Comment