home *** CD-ROM | disk | FTP | other *** search
/ PC World 1999 April / PCWorld_1999-04_cd.bin / Software / Vyzkuste / HomePlan / COMETEL.C < prev    next >
C/C++ Source or Header  |  1994-11-08  |  8KB  |  290 lines

  1. /*
  2.  
  3.     Convert comet elements in the formats used
  4.     by the Minor Planet Center (and in the Minor Planet
  5.     Electronic Circulars) to our CSV format.  Multiple
  6.     comet announcements can be extracted from a file
  7.     containing other irrelevant information.
  8.     
  9.     Designed and implemented by John Walker in November of 1994.
  10.     
  11.     PERIODIC COMET SHOEMAKER 4 (1994k)
  12.     
  13.                 . . .
  14.      
  15.          T = 1994 Oct. 31.231 TT          Peri. = 196.521
  16.          e = 0.52851                      Node  =  92.603   2000.0
  17.          q = 2.92503 AU                   Incl. =  25.345
  18.            a =  6.20375 AU     n = 0.063786     P =  15.45 years
  19.               1         2         3         4         5         6         7
  20.     01234567890123456789012345678901234567890123456789012345678901234567890
  21.  
  22.     COMET MUELLER (1994c)
  23.                                                                                
  24.                     . . .
  25.                                                                                                   
  26.          T = 1993 Dec.  3.990 TT          Peri. = 102.512
  27.                                              Node  =   4.933   2000.0
  28.          q = 1.81118 AU                   Incl. = 145.454
  29.               1         2         3         4         5         6         7
  30.     01234567890123456789012345678901234567890123456789012345678901234567890
  31.  
  32.     
  33.     Name,Perihelion time,Perihelion AU,Eccentricity,Long. perihelion,Long. node,Inclination,Semimajor axis,Period
  34.     P/Encke,94-02-09,0.331,0.85,186,335,11.9,7,0
  35.     P/Halley,86-02-09,0.587,0.97,112,59,162.2,26,0
  36.     P/Schwassman-Wachmann 1,89-10-26,5.772,0.04,50,313,9.4,17,0
  37.  
  38.     
  39. */
  40.  
  41. #include <stdio.h>
  42. #include <ctype.h>
  43. #include <string.h>
  44. #include <math.h>
  45.  
  46. #ifdef unix
  47. #define _strnicmp strncasecmp
  48. #endif
  49.  
  50. static char s[8][132];                    /* Buffer to hold complete entry */
  51.  
  52. static int rs(char *s, FILE *fp)
  53. {
  54.     if (fgets(s, 132, fp) == NULL) {
  55.         return 0;
  56.     }
  57.     while (strlen(s) > 0 && s[strlen(s) - 1] < ' ') {
  58.         s[strlen(s) - 1] = 0;
  59.     }
  60.     return 1;
  61. }
  62.  
  63. static void sc(char *b, int line, int start, int end) {
  64.     char *c = s[line];
  65.     int i, n;
  66.     
  67.     for (i = 0, n = start; n <= end; n++) {
  68.         if (c[n] == 0) {
  69.             break;
  70.         }
  71.         if (!isspace(c[n])) {
  72.             b[i++] = c[n];
  73.         }
  74.     }
  75.     b[i] = 0;
  76. }
  77.  
  78.  
  79. static void sct(char *b, int line, int start, int end)
  80. {
  81.     char *c = s[line], sb[132];
  82.  
  83.     memcpy(sb, c + start, (end - start) + 1);
  84.     sb[(end - start) + 1] = 0;
  85.     while (strlen(sb) > 0 && isspace(sb[strlen(sb) - 1])) {
  86.         sb[strlen(sb) - 1] = 0;
  87.     }
  88.     c = sb;
  89.     while (*c && isspace(*c)) {
  90.         c++;
  91.     }
  92.     strcpy(b, c);
  93. }
  94.  
  95.  
  96. int main(int argc, char *argv[])
  97. {
  98.     int i, running = 1, written = 0;
  99.     FILE *fi = stdin, *fo = stdout;            /* Input and output file names */
  100.     static char cname[80], epoch[80], periau[80], perilong[80],
  101.                 eccen[80], longnode[80], inclin[80], semimaj[80], period[80];
  102.     
  103.     if (argc > 1) {
  104.         fi = fopen(argv[1], "r");            /* Input file */
  105.         if (fi == NULL) {
  106.             fprintf(stderr, "Cannot open input file %s\n", argv[1]);
  107.             return 2;
  108.         }
  109.         if (argc > 2) {
  110.             fo = fopen(argv[2], "w");        /* Output file */
  111.             if (fo == NULL) {
  112.                 fprintf(stderr, "Cannot open output file %s\n", argv[2]);
  113.                 return 2;
  114.             }
  115.         }
  116.     }
  117.  
  118.     fprintf(fo, "Name,Perihelion time,Perihelion AU,Eccentricity,Long. perihelion,\
  119. Long. node,Inclination,Semimajor axis,Period\n");
  120.     
  121.     while (running) {
  122.         int periodic = -1;
  123.         char *u, *v;
  124.         
  125.         while (1) {
  126.             if (!rs(s[0], fi)) {
  127.                 running = 0;
  128.                 break;
  129.             }
  130.             if (strncmp(s[0], "COMET ", 6) == 0) {
  131.                 sct(cname, 0, 6, 80);
  132.                 periodic = 0;
  133.                 break;  
  134.             } else if (strncmp(s[0], "PERIODIC COMET ", 15) == 0) {
  135.                 sct(cname, 0, 15, 80);
  136.                 periodic = 1;
  137.                 break;
  138.             } 
  139.         }
  140.         
  141.         if (!running) {
  142.             break;
  143.         }
  144.         
  145.         /* Scan until we either find a line which begins with the "T ="
  146.            specification or run into another comet header (indicating
  147.            this circular didn't contain elements. */
  148.            
  149.         while (1) {
  150.             char t[132];
  151.         
  152.             if (!rs(s[0], fi)) {
  153.                 running = 0;
  154.                 break;
  155.             }
  156.             if (strncmp(s[0], "COMET ", 6) == 0) {
  157.                 sct(cname, 0, 6, 80);
  158.                 periodic = 0;
  159.                 continue;  
  160.             } else if (strncmp(s[0], "PERIODIC COMET ", 15) == 0) {
  161.                 sct(cname, 0, 15, 80);
  162.                 periodic = 1;
  163.                 continue;
  164.             }
  165.             sc(t, 0, 0, 80);
  166.             if (strncmp(t, "T=", 2) == 0 && isdigit(t[2])) {
  167.                 char y[20], m[20], daf[20];
  168.                 static char mname[] = "janfebmaraprmayjunjulaugsepoctnovdec";
  169.                 
  170.                 sscanf(u = strchr(s[0], '=') + 1, "%s %s", y, m);
  171.                 for (i = 0; i < 12; i++) {
  172.                     if (_strnicmp(m, mname + i * 3, 3) == 0) {
  173.                         sprintf(m, "%d", i + 1);
  174.                         break;
  175.                     }
  176.                 }
  177.                 
  178.                 /* Tiptoe up to the start of the year, since in the
  179.                    case of "Sept.199x" the month runs into the first
  180.                    digit of the year.  This code is relsilient in case
  181.                    a space is added later. */
  182.                 
  183.                 while (*u && isspace(*u)) {
  184.                     u++;
  185.                 }
  186.                 while (*u && !isspace(*u)) {
  187.                     u++;
  188.                 }
  189.                 while (*u && isspace(*u)) {
  190.                     u++;
  191.                 }
  192.                 while (*u && !isdigit(*u)) {
  193.                     u++;
  194.                 }
  195.                 sscanf(u, "%s", daf);
  196.                 sprintf(epoch, "%s-%s-%s", y, m, daf);
  197.                 v = strchr(u, '=');
  198.                 if (v != NULL) {
  199.                     sc(perilong, 0, (v + 1) - s[0], 80);
  200.                 } else {
  201.                     continue;
  202.                 }
  203.                 
  204.                 /* Process second line. */
  205.                 
  206.                 if (!rs(s[0], fi)) {
  207.                     running = 0;
  208.                     break;
  209.                 }
  210.                 sc(t, 0, 0, 80);
  211.                 if (strncmp(t, "e=", 2) == 0) {
  212.                     sscanf(u = strchr(s[0], '=') + 1, "%s", eccen);
  213.                     v = strchr(u, '='); 
  214.                 } else {
  215.                     strcpy(eccen, "1");            /* Parabolic */
  216.                     v = strchr(s[0], '=');
  217.                 }
  218.                 if (v != NULL) {
  219.                     sscanf(v + 1, "%s", longnode);
  220.                 } else {
  221.                     continue;
  222.                 }
  223.                 
  224.                 /* Process third line. */
  225.                 
  226.                 if (!rs(s[0], fi)) {
  227.                     running = 0;
  228.                     break;
  229.                 }
  230.                 u = strchr(s[0], '=');
  231.                 if (u != NULL) {
  232.                     v = strchr(u + 1, '=');
  233.                 }
  234.                 if (u != NULL && v != NULL) {
  235.                     sscanf(u + 1, "%s", periau);
  236.                     sscanf(v + 1, "%s", inclin);
  237.                 } else {
  238.                     continue;
  239.                 }
  240.                 
  241.                 /* Process fourth line if comet is periodic. */
  242.                 
  243.                 strcpy(semimaj, "");
  244.                 strcpy(period, "Parabolic");
  245.                 if (periodic) {
  246.                     if (!rs(s[0], fi)) {
  247.                         running = 0;
  248.                         break;
  249.                     }
  250.                     u = strchr(s[0], '=');
  251.                     if (u != NULL) {
  252.                         v = strchr(u + 1, '=');
  253.                         if (v != NULL) {
  254.                             v = strchr(v + 1, '=');
  255.                         }
  256.                     }
  257.                     if (u != NULL && v != NULL) {
  258.                         char t1[30], t2[30];
  259.                         
  260.                         sscanf(u + 1, "%s %s", t1, t2);
  261.                         sprintf(semimaj, "%s %s", t1, t2);
  262.                         sscanf(v + 1, "%s %s", t1, t2);
  263.                         sprintf(period, "%s %s", t1, t2);
  264.                     } else {
  265.                         continue;
  266.                     }
  267.                 }
  268.                  
  269.                 break;
  270.             } 
  271.         }
  272.         
  273.         if (!running) {
  274.             break;
  275.         }
  276.         
  277.         /* Output information in CSV format. */
  278.  
  279.         fprintf(fo, "%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
  280.                     cname, epoch, periau, eccen, perilong, longnode, inclin,
  281.                     semimaj, period);
  282.         written++;                    
  283.     }
  284.     
  285.     fclose(fi);
  286.     fclose(fo);
  287.     fprintf(stderr, "%d record%s written.\n", written, written == 1 ? "" : "s");        
  288.     
  289.     return 0;
  290. }