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.

  • python@lemmy.world
    link
    fedilink
    arrow-up
    17
    ·
    3 days ago

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

    weint in JavaSchrift

  • Randelung@lemmy.world
    link
    fedilink
    arrow-up
    16
    ·
    3 days ago

    Wir tun es nicht, weil es einfach ist, sondern weil wir dachten, dass es einfach sei.

    • Credo des Programmierers
  • d_k_bo@feddit.org
    link
    fedilink
    arrow-up
    12
    arrow-down
    1
    ·
    3 days ago

    Nun sitze ich seit 2h hier und lerne von Grund auf neu C

    Du könntest auch einfach Rost 🦀 lernen und das Programm wiederschreiben. Dann läuft es dank Nullkostenabstrahierungen auch lodernd schnell 🚀

      • excral@feddit.org
        link
        fedilink
        arrow-up
        3
        ·
        3 days ago

        Arduinos sollte man eigentlicher eh nicht mehr verwenden. Im Gegensatz zu z.B. den Raspberry Pico oder den ESP32 sind die komplett eingestaubte obsolete Technik. Der ATmega 328 ist ein über 15 Jahre alter 8 Bit (!) Controller. Und selbst wenn man die Arduino Plattform verwenden möchte, kann man das auch mit dem Pico oder ESP32 Controllern. Aber spätestens wenn man anfängt mit Interrupts zu spielen würde ich von der Arduino Plattform abraten

        • Kratzkopf@discuss.tchncs.de
          link
          fedilink
          arrow-up
          4
          ·
          2 days ago

          Ich lese jetzt nicht wirklich raus, was dagegen spricht einen Arduino verwenden, wenn einen die limitierte Hardware nicht einschränkt. Das war bei denen ja aber gefühlt schon immer so. Es ist halt ein sehr begrenzter Mikrocontroller, aber mit niedriger Einstiegsschwelle und für wahnsinnig viele Anwendungen absolut ausreichend. Ein ESP32 braucht auch ungefähr 100mal so viel Strom wie ein ATmega328. Es gibt mMn keinen Grund, die fünf Arduinos, die man noch in einer Kiste liegen hat, nicht mehr zu benutzen.

        • polle@feddit.org
          link
          fedilink
          arrow-up
          1
          ·
          2 days ago

          Durch die alte Technik flahst der Controller dafür auch sehr viel schneller. Ein esp32 finde ich deswegen extrem mühsam.

      • d_k_bo@feddit.org
        link
        fedilink
        arrow-up
        2
        ·
        3 days ago

        Ich habe was eingebettet angeht bisher nur mit einem ESP32-C3 gearbeitet. Geht es? Ja. Macht es Spaß? Nur so semi. Gerade Blauzahn NE ist noch ausbaufähig, aber da geschieht aktuell auch viel.

        • jenesaisquoi@feddit.org
          link
          fedilink
          English
          arrow-up
          2
          ·
          2 days ago

          Mir machte es Spaß. Kabelloses Netzwerk funktioniert einfach so aus der Kiste. Und Botschaft ist toll. Außerdem freue ich mich über RISIKO 5 - je mehr Konkurrenz für das amd64/aarch64 Duopol desto besser!

  • cows_are_underrated@feddit.orgOP
    link
    fedilink
    arrow-up
    7
    ·
    edit-2
    3 days ago

    Falls wer von euch zufälligerweise einen funktionierenden Code hat mit dem ich mir einfach die Werte von Variablen aus meiner config Datei ziehen kann würde ich mich darüber freuen.

    Syntax meiner config:

    Wert1 = 1
    Wert2 = 2.5

    Will das ganze dann irgendwie so implementieren:

    int Wert1 = getValue(“Wert1”);

    • excral@feddit.org
      link
      fedilink
      arrow-up
      4
      ·
      3 days ago

      Ist die Syntax deiner config-Datei fix? Sonst könntest du auch einfach eine C-Header-Datei als config-Datei verwenden und diese ganz normal includen.

        • anton@lemmy.blahaj.zone
          link
          fedilink
          arrow-up
          1
          ·
          5 hours 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.

        • Tlf@feddit.org
          link
          fedilink
          arrow-up
          5
          ·
          edit-2
          3 days ago

          Glaube in der Sprache der Wahl wird es nicht viel kürzer. Edit: fstream spielt nicht gerne auf Arduino, den Vorschlag das selbst zu implementieren spare ich mir daher.