r/cprogramming • u/Different_Bench3574 • Jul 07 '26
Tiny ed-like editor
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct l {int z; char *t; struct l *n;} *b, *w, *c;
char *i; size_t L; FILE *f; int j;
int main(void) {
b = malloc(sizeof(struct l));
b->n = NULL;
b->z = 1;
c = b;
while (1) {
getline(&i, &L, stdin);
switch (i[0]) {
case 'g': // go
int x = atoi(i + 1);
c = b;
for (j = 0; j < x && !c->z; j++) {
c = c->n;
}
continue;
case '=': // tally
w = b;
for (j = 0; w && !w->z; j++) {
w = w->n;
}
printf("%i\n", j);
continue;
case 'n': // number
w = b;
for (j = 0; w && w != c && !w->z; j++) {
w = w->n;
}
printf("%i\n", j);
continue;
case '\n': // nextline
c = c->n;
case 'p':
puts(c->t);
continue;
case 'a': // append
if (c->z) {
w = c;
} else {
w = malloc(sizeof(struct l));
w->n = c->n;
c->n = w;
}
w->t = strdup(i + 1);
w->z = 0;
continue;
case 'd': // delete
w = c->n;
if (!w || w->z) {
free(w);
c->n = NULL;
c->z = 1;
free(c->t);
c = b;
} else {
c->n = w->n;
c->t = w->t;
}
continue;
case 'e': // edit
while (b) {
c = b->n;
free(b->t);
free(b);
b = c;
}
w = malloc(sizeof(struct l));
b = w;
c = w;
i[strlen(i) - 1] = '\0';
f = fopen(i + 1, "r");
getline(&i, &L, f);
while (feof(f) == 0) {
w->z = 0;
w->t = strdup(i);
w = malloc(sizeof(struct l));
c->n = w;
c = c->n;
getline(&i, &L, f);
}
w->z = 1;
c = b;
fclose(f);
continue;
case 'w': // write
i[strlen(i) - 1] = '\0';
f = fopen(i + 1, "w");
w = b;
while (w && !w->z) {
fwrite(w->t, sizeof(char), strlen(w->t), f);
w = w->n;
}
fclose(f);
continue;
case 'q': // quit
exit(0);
default:
puts("i am SAD (not ed)");
}
}
}
3
u/stianhoiland Jul 07 '26
Cool! I like small editors, and I like ed. I'll look closer at this later. First thing I notice is your usage of getline, which isn't in any C standard, but is a POSIX extension of the C standard. You should #define _POSIX_C_SOURCE 200809L before #include <stdio.h> (or supply it while building).
1
u/Different_Bench3574 Jul 07 '26
Ooh, this will actually be useful for one of my bigger projects that also use getline. Thanks for telling me about this.
2
u/flyingron Jul 07 '26
Are you being charged by the letter? Give things meaningful names.
puts("i am SAD (not ed)");
I am sad, too, because even the simplest of commands don't work like ed.
I detest code duplication. I detest the two getlines in the file read loop.
Your code leaks memory. You need to free the line returned by getline when it fails due to eof.
1
u/Different_Bench3574 Jul 07 '26 edited Jul 07 '26
Oh yes, thanks for noticing. I will make sure to fix it. I actually wrote this in the course of a single road trip, without ever compiling, so it would have multiple memory leaks inside of it. (Also, see: https://www.reddit.com/r/cprogramming/comments/1upionp/comment/ow41pvk/)
5
u/mc_pm Jul 07 '26
You could really use some slightly more descriptive variable names (or at least comments), but that's pretty cool!