Align columns/C: Difference between revisions

From Rosetta Code
(moved from Column Aligner)
 
(No difference)

Revision as of 12:45, 6 February 2010

Align columns/C is part of Column Aligner. You may find other members of Column Aligner at Category:Column Aligner.

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <string.h>

struct linelement {

 char **wordlist;
 int longest;
 struct linelement *next;

};

typedef struct linelement line_t;

char *trim(char *s, int *len) {

 char *b;
 int l;
 while( (*s == ' ') || (*s == '\t') ) s++;
 b = s; 
 l = strlen(b);
 s += l; s--;
 while( (*s == ' ') || (*s == '\t') ) s--;
 s++; *s = 0;
 if ( l > *len ) *len = l;
 return b;

}

char **split(char *l, int c, int *longest) {

 int howmany, i;
 char **arr;
 char *n;
 if ( (n = strchr(l, 10)) != NULL ) *n = 0;
 if ( (n = strchr(l, 13)) != NULL ) *n = 0;
 for(howmany=1, i=0; l[i] != 0 ; i++) 
   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;

}


  1. define MAXLINELEN 1024
  2. define FILLCHAR ' '

/* decide the alignment */ enum textalign {

 LEFT_ALIGNED, RIGHT_ALIGNED, CENTER_ALIGNED

}; const int alignment = CENTER_ALIGNED;


int main() {

 char buf[MAXLINELEN];
 line_t *head, *cur;
 char *lb;
 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>