Align columns/C: Difference between revisions

1,310 bytes removed ,  12 years ago
replaced with clean method
(replaced with clean method)
Line 2:
 
<lang c>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
char *str =
struct linelement {
"Given$a$text$file$of$many$lines,$where$fields$within$a$line$\n"
char **wordlist;
"are$delineated$by$a$single$'dollar'$character,$write$a$program\n"
int longest;
"that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$\n"
struct linelement *next;
"column$are$separated$by$at$least$one$space.\n"
};
"Further,$allow$for$each$word$in$a$column$to$be$either$left$\n"
"justified,$right$justified,$or$center$justified$within$its$column.";
 
void align(char *in, char alignment)
typedef struct linelement line_t;
 
char *trim(char *s, int *len)
{
int col, i, l, r;
char *b;
int w[1024] = {0};
int l;
char *s = in;
 
while( for (*s == 'in, ')i ||= (*scol == '\t')0; )s[i]; s += i +; 1) {
for (i = 0; s[i] && s[i] != '$' && s[i] != '\n'; i++);
b = s;
l = strlen(b);
s += l; s--;
while( (*s == ' ') || (*s == '\t') ) s--;
s++; *s = 0;
if ( l > *len ) *len = l;
return b;
}
 
if (i > w[col]) w[col] = i;
char **split(char *l, int c, int *longest)
{
int howmany, i;
char **arr;
char *n;
 
if (col++ (n >= strchr1024) abort(l, 10)); !=/* NULLartifical )limit *n = 0;/
if ( (n = strchr(l, 13)) != NULL ) *n = 0;
 
if for(howmany=1, i=0; ls[i] !== 0'\n') ;col i++)= 0;
if (!s[i]) break;
if ( (l[i]==c) && ((i+1) < strlen(l))) howmany++;
}
arr = malloc(sizeof(char *) * (howmany+1));
arr[0] = NULL;
if ( arr != NULL ) {
n = l;
for(i=0; i < howmany; i++) {
arr[i] = n;
n = strchr(n, c);
if ( n == NULL ) { break; }
*n = 0; n++;
arr[i] = trim(arr[i], longest);
}
}
arr[howmany] = NULL;
return arr;
}
 
for (s = in, i = col = 0; s[i]; s += i + 1) {
for (i = 0; s[i] && s[i] != '$' && s[i] != '\n'; i++);
 
switch(alignment) {
#define MAXLINELEN 1024
case 'l': r = w[col] - i; break;
#define FILLCHAR ' '
case 'c': r = (w[col] - i)/2; break;
case 'r': r = 0; break;
}
l = w[col++] - i - r + 1;
 
while (l--) putchar(' ');
/* decide the alignment */
printf("%.*s", i, s);
enum textalign {
while (r--) putchar(' ');
LEFT_ALIGNED, RIGHT_ALIGNED, CENTER_ALIGNED
};
const int alignment = CENTER_ALIGNED;
 
if (s[i] != '$') {
putchar('\n');
col = 0;
}
if (!s[i]) break;
}
}
 
int main(void)
{
puts("\n---- right ----"); align(str, 'r');
char buf[MAXLINELEN];
puts("\n---- left ----"); align(str, 'l');
line_t *head, *cur;
puts("\n---- center ----"); align(str, 'c');
char *lb;
return 0;
int reallongest, i, len, ipos;
 
head = malloc(sizeof(line_t));
memset(head, 0, sizeof(line_t));
 
/* for each line, split it ($-separated words) */
cur = head;
while ( fgets(buf, MAXLINELEN, stdin) != NULL ) {
lb = malloc(strlen(buf));
strncpy(lb, buf, strlen(buf));
cur->wordlist = split(lb, '$', &(cur->longest));
cur->next = malloc(sizeof(line_t));
memset(cur->next, 0, sizeof(line_t));
cur = cur->next;
}
cur->next = NULL; /* last node is a end-marker */
 
/* each line holds the longest word length; find the
longest among all lines; this determines the width
of all columns */
reallongest = head->longest;
cur = head;
while( cur->next != NULL ) {
if ( cur->longest > reallongest )
reallongest = cur->longest;
cur = cur->next;
}
 
reallongest++;
buf[reallongest] = 0; /* no bounds check... */
 
/* print the columns */
cur = head;
while( cur->next != NULL ) {
for(i=0; cur->wordlist[i] != NULL; i++) {
len = strlen(cur->wordlist[i]);
switch(alignment) {
case LEFT_ALIGNED:
ipos = 0;
break;
case RIGHT_ALIGNED:
ipos = reallongest - len;
break;
case CENTER_ALIGNED:
ipos = (reallongest - len)/2;
break;
}
memset(buf, FILLCHAR, reallongest);
memcpy(buf+ipos, cur->wordlist[i], len);
printf("%s ", buf);
}
printf("\n");
cur = cur->next;
}
}</lang>
Anonymous user