Re: adding colums to text



Bill Cunningham wrote:
I have a row of values like such, placed in a text file by fprintf.

10.50
10.25
10.00
10.75
11.00

What I want to do to the above colum is add a new column right beside it which is a total of these values and then average them in another column. For example.

11.00 52.50

In another column is the average of the 5.

11.00 52.50 10.50

I am assuming that fprintf is going to have to be used and maybe freopen.

Text files and linked lists, go together like hot dogs and mustard.

/* BEGIN new.c output */

File is open for writing.
File lines:
10.50
10.25
10.00
10.75
11.00
File is closed.

File is open for reading.
Reading file into a linked list...
File is closed.

File is open for writing.
List is freed.
File is closed.

File is open for reading.
File lines:
10.50 52.50 10.50
10.25 52.50 10.50
10.00 52.50 10.50
10.75 52.50 10.50
11.00 52.50 10.50
Line reading buffer is freed.
File is closed.
File is removed.

/* END new.c output */



/* BEGIN new.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#define DOUBLES {10.5, 10.25, 10, 10.75, 11}
#define NMEMB(A) (sizeof (A) / sizeof *(A))

typedef struct list_node {
struct list_node *next;
void *data;
} list_type;

int get_line(char **lineptr, size_t *n, FILE *stream);
list_type *list_append
(list_type **head, list_type *tail, void *data, size_t size);
void list_free(list_type *node, void (*free_data)(void *));

int main(void)
{
int rc;
size_t index;
FILE *fp;
long unsigned count = 0;
double sum = 0.0;
char fn[L_tmpnam];
double array[] = DOUBLES;
char *buff = NULL;
size_t size = 0;
list_type *head = NULL;
list_type *tail = NULL;

puts("/* BEGIN new.c output */\n");
tmpnam(fn);
fp = fopen(fn, "w");
if (fp == NULL) {
fputs("fopen(fn), \"w\") == NULL\n", stderr);
exit(EXIT_FAILURE);
}
puts("File is open for writing.");
puts("File lines:");
for (index = 0; index != NMEMB(array); ++index) {
fprintf( fp, "%.2f\n", array[index]);
fprintf(stdout, "%.2f\n", array[index]);
}
fclose(fp);
puts("File is closed.\n");
fp = fopen(fn, "r");
if (fp == NULL) {
fputs("fopen(fn, \"r\") == NULL\n", stderr);
exit(EXIT_FAILURE);
}
puts("File is open for reading.");
puts("Reading file into a linked list...");
while ((rc = get_line(&buff, &size, fp)) > 0) {
tail = list_append(&head, tail, buff, rc);
if (tail == NULL) {
fputs("tail == NULL\n", stderr);
break;
}
++count;
}
fclose(fp);
puts("File is closed.");
fp = fopen(fn, "w");
if (fp == NULL) {
fputs("fopen(fn), \"w\") == NULL\n", stderr);
exit(EXIT_FAILURE);
}
puts("\nFile is open for writing.");
for (tail = head; tail != NULL; tail = tail -> next) {
sum += atof(tail -> data);
}
for (tail = head, index = 0; index != count; ++index) {
fprintf(fp, "%.2f %.2f %.2f\n",
array[index], sum, sum / count);
tail = tail -> next;
if (tail == NULL) {
break;
}
}
list_free(head, free);
puts("List is freed.");
fclose(fp);
puts("File is closed.");
fp = fopen(fn, "r");
if (fp == NULL) {
fputs("fopen(fn, \"r\") == NULL\n", stderr);
exit(EXIT_FAILURE);
}
puts("\nFile is open for reading.");
puts("File lines:");
while ((rc = get_line(&buff, &size, fp)) > 0) {
fprintf(stdout, "%s\n", buff);
}
free(buff);
buff = NULL;
size = 0;
puts("Line reading buffer is freed.");
fclose(fp);
puts("File is closed.");
remove(fn);
puts("File is removed.");
puts("\n/* END new.c output */");
return 0;
}

int get_line(char **lineptr, size_t *n, FILE *stream)
{
int rc;
void *p;
size_t count;

count = 0;
while ((rc = getc(stream)) != EOF
|| !feof(stream) && !ferror(stream))
{
++count;
if (count == (size_t)-2) {
if (rc != '\n') {
(*lineptr)[count] = '\0';
(*lineptr)[count - 1] = (char)rc;
} else {
(*lineptr)[count - 1] = '\0';
}
break;
}
if (count + 2 > *n) {
p = realloc(*lineptr, count + 2);
if (p == NULL) {
if (*n > count) {
if (rc != '\n') {
(*lineptr)[count] = '\0';
(*lineptr)[count - 1] = (char)rc;
} else {
(*lineptr)[count - 1] = '\0';
}
} else {
if (*n != 0) {
**lineptr = '\0';
}
ungetc(rc, stream);
}
count = 0;
break;
}
*lineptr = p;
*n = count + 2;
}
if (rc != '\n') {
(*lineptr)[count - 1] = (char)rc;
} else {
(*lineptr)[count - 1] = '\0';
break;
}
}
if (rc != EOF || !feof(stream) && !ferror(stream)) {
rc = INT_MAX > count ? count : INT_MAX;
} else {
if (*n > count) {
(*lineptr)[count] = '\0';
}
}
return rc;
}

list_type *list_append
(list_type **head, list_type *tail, void *data, size_t size)
{
list_type *node;

node = malloc(sizeof *node);
if (node != NULL) {
node -> next = NULL;
node -> data = malloc(size);
if (node -> data != NULL) {
memcpy(node -> data, data, size);
if (*head != NULL) {
tail -> next = node;
} else {
*head = node;
}
} else {
free(node);
node = NULL;
}
}
return node;
}

void list_free(list_type *node, void (*free_data)(void *))
{
list_type *next_node;

while (node != NULL) {
next_node = node -> next;
free_data(node -> data);
free(node);
node = next_node;
}
}

/* END new.c */

--
pete
.



Relevant Pages

  • Re: how to read integers from a text file
    ... Reading file into a linked list... ... struct list_node *next; ... int main ... fprintf(stdout, "%4s,", buff); ...
    (comp.lang.c)
  • Re: fgets() equivalent?
    ... When reading text, if a bare LF is read, it's not a newline, but fgetsstops reading anyway and stores the LF into the program's buffer. ... In other words you can just DUMP a unix file to a printer without taking into account how the HEAD is moving. ... a consecutive pair of characters CR-LF, fields within a line are separated by tab characters, and sub-lines within a field are separated by bare LF characters. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: fread()
    ... > int i,istat,iaccum,intype; ... reading binary data from standard input? ... Use sizeof (float), or even better, sizeof *floatarray, instead. ... FLOAT, and set istat accordingly? ...
    (comp.lang.c)
  • Re: More on abstract musical conception and performance (WAS Re: Mahler #6)
    ... >>> has seemingly tried to explain by discussing the intermediation of the ... Some people can get closer to what was in Beethoven's head ... > you are supporting the contention that Paul took an untenable position ... I do such "abstract performance" for myself via score reading. ...
    (rec.music.classical.recordings)
  • River Flow Rates and Safety
    ... involved in the planning of Reading Uni Head. ... Back down on the Reading stretch today, however, we were on red boards ... despite the flow rate of the river being less than it was on the Trent ... river flow rate meter below the bridge - would it not be possible to ...
    (rec.sport.rowing)