Friday, March 14, 2008

an assortment of C

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

#define LINE_SIZE 10000

/**
* Reads doubles from in until EOF.
* If le n is not null, *len is set to
* the number of elements read.
* The caller is responsible for freeing the
* memory of the returned object.
* Returns null in case of an error.
*/
double* readArray(FILE* in, int* len)
{
const char* SPACES = " \t\r\n";
char* line = malloc(LINE_SIZE);
int capacity = 100;
double* y = malloc(sizeof(double) * capacity);
int n = 0;
while (!ferror(in) && !feof(in)) {
if (fgets(line, LINE_SIZE, in)) {
const char* next = line;
while (*next) {
next += strspn(next, SPACES);
if (*next) {
double v;
if (sscanf(next, "%lf", &v) == 1) {
if (capacity == n) {
capacity *= 2;
y = realloc(y, capacity * sizeof(double));
}

y[n] = v;
++n;
}
else {
free(line);
free(y);
return 0;
}
}
next += strcspn(next, SPACES);
}
}
else {
if (!feof(in)) {
free(line);
free(y);
return 0;
}
}
}

if (len) {
*len = n;
}

return y;
}

/**
* Reads doubles from file.
* If len is not null, *len is set to the
* number of elements read.
* The caller is responsible for freeing the
* memory of the returned object.
* Returns null in case of an error.
*/
double* readArrayFromFile(const char* file, int* len)
{
FILE* in = fopen(file, "r");
double* result = 0;
if (!in) {
fprintf(stderr, "Problem opening %s\n", file);
perror("");
}
else {
result = readArray(in, len);
fclose(in);
}
return result;
}

/**
* Returns 1 if tail is a suffix of s, 0 otherwise.
*/
int endsWith(const char* s, const char* tail)
{
const int sLen = strlen(s);
const int tailLen = strlen(tail);
if (sLen >= tailLen) {
return strcmp(s + sLen - tailLen, tail) == 0;
}
else {
return 0;
}
}

int remove(double* y, const int len,
const double toRemove)
{
int newLen = 0;
int i;

for (i = 0; i < len; ++i) {
const double yi = y[i];
if (yi != toRemove) {
y[newLen] = yi;
++newLen;
}
}
return newLen;
}

No comments: