burleigh@silver.bacs.indiana.edu (Frank Burleigh) (06/21/89)
I am (very) new to C, and need suggestions from the net on the proper way(s) to handle this problem. It involves reading files whose lines may have a variable number of space-separated values. I have several pairs of files (FILEA, FILEB). FILEA of each pair contains several groups of lines with a constant (VALUES) number of values on each line throughout the file. FILEB contains one line with VALUES values corresponding to each group of lines in FILEA. The ith value on the jth line in FILEB is used to adjust the ith value on each line in the jth group of lines in FILEA. The vexing problem for me is that each pair of FILEA and FILEB files has a different number of values on the input lines. I could compile different versions of the program to accommodate each pair, but that seems less than elegant. Apparently this is a problem to be solved by passing a variable number of arguments to vscanf() and vprintf() with the va_... macros in <stdarg.h>, but the procedures for this sort of application are not clear to me (from KR2 or Turbo C reference). I'm especially eager to see sample code to help me through this. Thanks in advance. Frank Burleigh burleigh@silver.bacs.indiana.edu USENET: ...rutgers!iuvax!silver!burleigh BITNET: BURLEIGH@IUBACS.BITNET Department of Sociology, Indiana University, Bloomington, Indiana 47405
chris@mimsy.UUCP (Chris Torek) (06/23/89)
In article <22380@iuvax.cs.indiana.edu> burleigh@silver.bacs.indiana.edu (Frank Burleigh) writes: >The vexing problem for me is that each pair of FILEA and FILEB >files has a different number of values on the input lines. I >could compile different versions of the program to accommodate >each pair, but that seems less than elegant. Indeed. >Apparently this is a problem to be solved by passing a variable >number of arguments to vscanf() and vprintf() with the va_... >macros in <stdarg.h>, but the procedures for this sort of >application are not clear to me (from KR2 or Turbo C reference). I do not know what led you to leap from `read a variable number of values' to `supply a variable argument list to an I/O function'. There is a much simpler way to read a variable number of values, and that is to make a variable number of read calls. For instance: #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <limits.h> #include <string.h> ... long v; char *ptr, *eptr; FILE *stream; char buf[SIZE]; ... if (fgets(buf, sizeof(buf), stream) == NULL) { ... handle EOF or error ... } ptr = buf; for (i = 0; i < values_per_line; i++) { ptr = strspn(ptr, " \t"); /* or whatever */ if (ptr == NULL || *ptr == '#') { /* # => comment */ ... handle ran-out-of-values ... } errno = 0; v = strtol(ptr, &eptr, 0); if ((v == LONG_MIN || v == LONG_MAX) && errno == ERANGE) { ... handle value out of range ... } if (ptr == eptr) { ... handle no digits ... } } if (ptr) { ptr = strspn(ptr, " \t"); if (ptr && *ptr != '#') { ... handle too much on line ... } } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris