this post was submitted on 26 Jun 2025
45 points (95.9% liked)

ich_iel

3692 readers
625 users here now

Die offizielle Zweigstelle von ich_iel im Fediversum.

Alle Pfosten müssen den Titel 'ich_iel' haben, der Unterstrich darf durch ein beliebiges Symbol oder Bildschriftzeichen ersetzt werden. Ihr dürft euch frei entfalten!


Matrix


📱 Empfohlene Schlaufon-Applikationen für Lassmich


Befreundete Kommunen:

!wir_iel@feddit.org

!i_itrl@feddit.org

!ich_ial@lemmy.world

!zunftgemeinde@feddit.org

!ki_iel@feddit.org


Sonstiges:

Zangendeutsch-Wörterbuch


Regeln:

1. Seid nett zueinander

Diskriminierung anderer Benutzer, Beleidigungen und Provokationen sind verboten.

2. Pfosten müssen den Titel 'ich_iel' oder 'ich iel' haben

Nur Pfosten mit dem Titel 'ich_iel' oder 'ich iel' sind zugelassen. Alle anderen werden automatisch entfernt.

Unterstrich oder Abstand dürfen durch ein beliebiges Textsymbol oder bis zu drei beliebige Emojis ersetzt werden.

3. Keine Hochwähl-Maimais oder (Eigen)werbung

Alle Pfosten, die um Hochwählis bitten oder Werbung beinhalten werden entfernt. Hiermit ist auch Eigenwerbung gemeint, z.b. für andere Gemeinschaften.

4. Keine Bildschirmschüsse von Unterhaltungen

Alle Pfosten, die Bildschirmschüsse von Unterhaltungen, wie beispielsweise aus WasistApplikaton oder Zwietracht zeigen, sind nicht erlaubt. Hierzu zählen auch Unterhaltungen mit KIs.

5. Keine kantigen Beiträge oder Meta-Beiträge

ich_iel ist kein kantiges Maimai-Brett. Meta-Beiträge, insbesondere über gelöschte oder gesperrte Beiträge, sind nicht erlaubt.

6. Keine Überfälle

Wer einen Überfall auf eine andere Gemeinschaft plant, muss diesen zuerst mit den Mods abklären. Brigadieren ist strengstens verboten.

7. Keine Ü40-Maimais

Maimais, die es bereits in die WasistApplikation-Familienplauderei geschafft haben oder von Rüdiger beim letzten Stammtisch herumgezeigt wurden, sind besser auf /c/ichbin40undlustig aufgehoben.

8. ich_iel ist eine humoristische Plattform

Alle Pfosten auf ich_iel müssen humorvoll gestaltet sein. Humor ist subjektiv, aber ein Pfosten muss zumindest einen humoristischen Anspruch haben. Die Atmosphäre auf ich_iel soll humorvoll und locker gehalten werden.

9. Keine Polemik, keine Köderbeiträge, keine Falschmeldungen

Beiträge, die wegen Polemik negativ auffallen, sind nicht gestattet. Desweiteren sind Pfosten nicht gestattet, die primär Empörung, Aufregung, Wut o.Ä. über ein (insbesonders, aber nicht nur) politisches Thema hervorrufen sollen. Die Verbreitung von Falschmeldungen ist bei uns nicht erlaubt.


Bitte beachtet auch die Regeln von Feddit.org

founded 1 year ago
MODERATORS
 

Die berühmten letzten Worte eines Programmierers: Das sollte eigentlich schnell gehen.

Ich wollte doch nur eine super simple Methode um ein paar Variablen in mein C-Skript zu bekommen, damit im nachhinein der Endnutzer nicht im Code rumpfuschen muss. Nun sitze ich seit 2h hier und lerne von Grund auf neu C (ich habe das vorher nur für die Programmierung eines Arduinos genutzt).

Wenigstens werde ich für den Kram bezahlt.

you are viewing a single comment's thread
view the rest of the comments
[–] anton@lemmy.blahaj.zone 1 points 2 days ago

Auf dem Arduino kannst du keine Dateien lesen, es sei den du willst die über serial senden, deshalb musst du die Werte in dein Programm kompilieren.

will eher ungerne den User in einer C-Header Datei rum spielen lassen

Dann lass deine user deine config schreiben und generiere eine header Datei daraus.
Ich habe mal meine C-Kenntnisse raus gekramt.

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

#define BUFFER_LEN 1024
#define MIN_STRONG_SIZE 16
#define IN_FILE_DEFAULT "config.txt"
#define OUT_FILE_DEFAULT "config.h"

typedef struct String {
	size_t length;
	size_t size;
	char content[];
} String;

typedef struct Variable {
	String* name;
	int intPart;
	int fracPart;
	bool isNegative;
	bool hasFraction;
} Variable;

FILE* outFile;

void storeVariable(Variable variable) {
	fprintf(outFile, "#define VAR_%s ", variable.name->content);
	if (variable.isNegative)
		fprintf(outFile, "-");
	fprintf(outFile, "%d", variable.intPart);
	if (variable.hasFraction)
		fprintf(outFile, ".%d", variable.fracPart);
	fprintf(outFile, "\n");
	free(variable.name);
}

String* newString(size_t size) {
	if (size < MIN_STRONG_SIZE) {
		size = MIN_STRONG_SIZE;
	}
	String* string = calloc(1, sizeof(String) + size);
	if (string == NULL) {
		fprintf(stderr, "allocation error");
		exit(3);
	}
	string->size = size;
	return string;
}

String* appendToString(String* string, char c) {
	if (string == NULL) {
		fprintf(stderr, "null pointer error");
		exit(4);
	}
	if (string->length+1 >= string->size) {
		string->size *= 2;
		string = realloc(string, sizeof(String) + string->size);
		if (string == NULL) {
			fprintf(stderr, "allocation error");
			exit(3);
		}
	}
	string->content[string->length] = c;
	string->content[string->length+1] = '\0';
	string->length++;
	return string;
}


typedef enum ParseMode {
	VAR_NAME_START = 0,
	VAR_NAME,
	INTEGER_START,
	INTEGER,
	FRACTION,
} ParseMode;

void handleChar(char c);

int main(int argc, char** argv) {
	char* confFileName = IN_FILE_DEFAULT;
	char* headerFileName = OUT_FILE_DEFAULT;
	if (argc > 1) {
		if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
			printf("usage: %s config_file output_file\n", argv[0]);
			printf("if no files get specified, the defaults are: %s %s\n", IN_FILE_DEFAULT, OUT_FILE_DEFAULT);
			return 0;
		}
		confFileName = argv[1];
	}
	if (argc > 2) {
		headerFileName = argv[2];
	}

	FILE* file = fopen(confFileName, "r");
	if (file == NULL) {
		fprintf(stderr, "can't open input file %s", confFileName);
		return 1;
	}
	outFile = fopen(headerFileName, "w");
	if (outFile == NULL) {
		fprintf(stderr, "can't open output file %s", headerFileName);
		return 1;
	}

	char buffer[BUFFER_LEN];
	unsigned long amountRead = fread(buffer, 1, BUFFER_LEN, file);
	while (amountRead > 0) {
		for (int i = 0; i < amountRead; i++) {
			handleChar(buffer[i]);
		}
		amountRead = fread(buffer, 1, BUFFER_LEN, file);
	}
	handleChar('\n');
	fclose(file);
	fclose(outFile);
	return 0;
}

ParseMode mode;
Variable state = {0};

void handleChar(char c) {
	if (c == ' ') {
		return;
	}
	switch (mode) {
		case VAR_NAME_START:
			if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {
				state.name = newString(20);
				state.name = appendToString(state.name, c);
				mode = VAR_NAME;
			} else {
				fprintf(stderr, "error on '%c': variable names must start with a letter", c);
				exit(2);
			}
			break;
		case VAR_NAME:
			if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '_')) {
				state.name = appendToString(state.name, c);
			} else if (c == '=') {
				mode = INTEGER;
			} else {
				fprintf(stderr, "name error on '%c': variable names consist of alphanumeric characters and underscores", c);
				exit(2);
			}
			break;
		case INTEGER_START:
			if (c == '-') {
				state.isNegative = true;
				state.intPart = 0;
			} else if ('0' <= c && c <= '9') {
				state.intPart = c - '0';
			} else {
				fprintf(stderr, "number error on '%c': expected digit or '-'", c);
				exit(2);
			}
			break;
		case INTEGER:
			if ('0' <= c && c <= '9') {
				state.intPart = state.intPart * 10 + c - '0';
			} else if (c == '\n') {
				mode = VAR_NAME_START;
				storeVariable(state);
				Variable empty = {0};
				state = empty;
			} else if (c == '.') {
				mode = FRACTION;
				state.hasFraction = true;
			} else {
				fprintf(stderr, "number error on '%c':  expected digit or '.'", c);
				exit(2);
			}
			break;
		case FRACTION:
			if ('0' <= c && c <= '9') {
				state.intPart = state.intPart * 10 + c - '0';
			} else if (c == '\n') {
				mode = VAR_NAME_START;
				storeVariable(state);
				Variable empty = {0};
				state = empty;
			} else {
				fprintf(stderr, "number error on '%c':  expected digit", c);
				exit(2);
			}
			break;
	}
}

Man sollte es wahrscheinlich in header und source aufteilen, und die strings sind vielleicht overkill, aber für ein one-of pass es schon. Wenn die variablen nach dem parsen anders verwenden willst, musst du nur storeVariable abändern.