Modularisierung



  • knivil schrieb:

    char cmdFilename[1024] = "";
    

    Kann mir mal jemand expliziet beschreiben, was hier genau passiert ...

    das ist ein char-array mit 1024 elementen und das erste wird auf 0 gesetzt.
    🙂



  • Hallo,

    die Länge der String-Variable möchte ich über eine Konstante definieren, die in einer anderen Header-Datei liegt.
    Wie wird denn diese Header-Datei in die Header-Datei inkludiert, in welcher der String definiert wird?

    In einem nächsten Schritt möchte ich gerne den aktuellen Pfad auslesen und dafür einen entsprechenden String zur Verfügung stellen. Wäre es möglich mir ein kurzes Beispiel zu geben, wie man
    1. die erforderliche Länge des Strings für das Working-Directory bestimmt
    2. diesen String dynamisch auspannt

    Besten Dank



  • Phil270307 schrieb:

    die Länge der String-Variable möchte ich über eine Konstante definieren, die in einer anderen Header-Datei liegt.
    Wie wird denn diese Header-Datei in die Header-Datei inkludiert, in welcher der String definiert wird?

    in die eine .h datei machste erstmal die konstante als #define rein. dann inkludierst du diese datei in jedem .c-file bevor du die datei mit der string-definition inkludierst. du könntest du auch die konstanten-h von der string-h selber inkludieren lassen. ach ja, und verwende 'inlcude guards', also sowas ähnliches:

    #ifndef MY_CONSTANTS
    #define MY_CONSTANTS
    ...
    #define ... ... // hier alle konstanten rein
    ...
    #endif
    

    ^^das brauchste, damit mehrfaches includen nicht den compile-vorgang abbricht.

    Phil270307 schrieb:

    1. die erforderliche Länge des Strings für das Working-Directory bestimmt

    unter windoofs gibt's die konstante MAX_PATH, aber ich weiss nicht, ob die brauchbar ist.

    Phil270307 schrieb:

    2. diesen String dynamisch auspannt

    ausspannt oder aufspannt? wie auch immer, was meinst du damit?
    🙂



  • ok, die Definition der Konstanten mit #define ist mir klar.

    Die Strings, die ich für meine Dateipfade verwenden liegen in einer anderen Header-Datei und werden durch die Konstanten begrenzt.

    konst.h

    #define MAXSTR1 = 512
    

    globStrings.h

    #include "konst.h"
    
    char command[MAXSTR1] = "";
    

    Aber das funktioniert noch nicht ....
    Muss ich für die Definition des Strings command noch eine *.c-Datei anlegen?

    P.S.:
    Meine Verzeichnisstrutkur sieht wie folgt aus:

    src/inc/.h
    src/obj/
    .o
    src/obj/Makefile
    src/*.c



  • Hallo,

    ich möchte gerne noch eine Frage stellen:
    Ist es möglich zur Laufzeit eine Struktur oder auch ein Feld einer Struktur zu allokieren, die selbst ein Feld beinhaltet, das dynamisch augespannt werden kann?

    Bsp:

    struct MyDataTyp {
     int A;
     float B;
     ....
    }
    

    An der Stelle, die ich mit "..." markiert habe sollte nun noch ein int-Feld erzeugt werden, dass N Elemente besitzt. Wie genau geht das?



  • Phil270307 schrieb:

    Hallo,

    ich möchte gerne noch eine Frage stellen:
    Ist es möglich zur Laufzeit eine Struktur oder auch ein Feld einer Struktur zu allokieren, die selbst ein Feld beinhaltet, das dynamisch augespannt werden kann?

    Si! Do you gucking here:

    typedef struct
    {
    	int n; // speichert die anzahl der dynamic_int elemente.
    	int* dynamic_int;
    
    }DynamicStruct;
    
    DynamicStruct* dynamic_struct_factory ( int n )
    {
    	DynamicStruct* _new = malloc (sizeof(DynamicStruct));
    	if ( _new != NULL )
    	{
    		if ( NULL ==(_new->dynamic_int = malloc ( n*sizeof(int))))
    		{
    			free (_new);
    			_new = NULL;
    		}
    		else
    			_new->n = n;
    	}
    	return _new;
    }
    
    void dynamic_struct_free ( DynamicStruct* pds )
    {
    	free (pds->dynamic_int);
    	free (pds);
    }
    
    int main()
    {	
    	int N = 100;
    	DynamicStruct* pds = dynamic_struct_factory (N);
            if ( pds == NULL )
    	    fprintf(stderr, "Shit happens: %s\n", strerror(errno));
    	// do something with it ...
    	dynamic_struct_free (pds); // free memory.
    	return 0;
    }
    

    SEEYA
    B.B. ( the bigger one )



  • Hallo,

    ich habe das Programm nachvollzogen und es auf meine Bedürfnisse erweitert. Dabei bin ich auf ein Problem/Fehler gestoßen, wenn ich versuche die allocate-Funktion in ein anderes Modula auszulagern.

    Hier mein Beispiel:
    ------------------------------------------------------------------------------
    ftypes.h

    typedef struct {
      char string[1000];
      int number;
    } Blade;
    
    typedef struct {
      int elements;
      Blade *pBlade;
    } Domain;
    

    ------------------------------------------------------------------------------
    allocate.h
    ------------------------------------------------------------------------------

    #include "ftypes.h"
    
    Domain* allocate(int n);
    

    ------------------------------------------------------------------------------
    allocate.c
    ------------------------------------------------------------------------------

    #include <stdlib.h>
    #include "alloc.h"
    #include "ftypes.h"
    
    Domain* allocate(int n) {
      Domain *newDomain = malloc(sizeof(Domain));
      if (newDomain != NULL) {
        newDomain->pBlade = malloc(sizeof(Blade)*n); 
        if (newDomain->pBlade != NULL) {
          newDomain->elements = n;
        } else {
          printf("Fehler 2!\n");
        }
      } else {
        printf("Fehler 1\n");
      }
      return newDomain;
    }
    

    bsp.c
    ------------------------------------------------------------------------------

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "ftypes.h"
    #include "alloc.h"
    
    int main(void) {
      int ret;
      int retval;
      int i, n = 10;
      Domain *pDomain;
    
      pDomain = allocate(n);
      for (i=0;i<pDomain->elements;i++) {
        pDomain->pBlade[i].number = i*10;
        strcpy(pDomain->pBlade[i].string,"Beispieltext");
      }
    
      for (i=0;i<pDomain->elements;i++) {
        printf("Element [%d]: '%d'\n", i+1, pDomain->pBlade[i].number);
      }
    
      free(pDomain);
      return 0;
    }
    

    Wenn ich versuche das Programm zu übersetzen, erhalte ich folgende Fehler:

    gcc alloc.c bsp5.c -o bsp5.exe
    In file included from alloc.c:3:
    ftypes.h:4: Fehler: In Konflikt stehende Typen für »Blade«
    ftypes.h:4: Fehler: Vorherige Deklaration von »Blade« war hier
    ftypes.h:9: Fehler: In Konflikt stehende Typen für »Domain«
    ftypes.h:9: Fehler: Vorherige Deklaration von »Domain« war hier
    alloc.c:5: Fehler: In Konflikt stehende Typen für »allocate«
    alloc.h:3: Fehler: Vorherige Deklaration von »allocate« war hier
    alloc.c: In Funktion »allocate«:
    alloc.c:12: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »printf«
    alloc.c:15: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »printf«
    In file included from alloc.h:1,
                     from bsp5.c:6:
    ftypes.h:4: Fehler: In Konflikt stehende Typen für »Blade«
    ftypes.h:4: Fehler: Vorherige Deklaration von »Blade« war hier
    ftypes.h:9: Fehler: In Konflikt stehende Typen für »Domain«
    ftypes.h:9: Fehler: Vorherige Deklaration von »Domain« war hier
    

    Woran liegt's ?



  • Sieht mir nach fehlenden Includeguards aus.



  • Was beudetet das?





  • Die Includeguards verhindern mehrmaliges Einbinden.
    Schreib mal deine ftypes.h so:

    // ftypes.h
    
    #ifndef FTYPES_H
    #define FTYPES_H
    
    typedef struct {
      char string[1000];
      int number;
    } Blade;
    
    typedef struct {
      int elements;
      Blade *pBlade;
    } Domain;
    
    #endif
    


  • supertux schrieb:

    Include guards

    😃



  • Entschuldigung, blöde Frage, aber ich kriege das immer noch nicht zum laufen.
    Also ich versuche genau das hier zu übersetzen...

    // allocmem.h
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "inc/allocmem.h"
    #include "inc/blade.h"
    #include "inc/sendmsg.h"
    
    /* *************************************************************************** */
    
    Domain* allocateDomain(int elements) {
      Domain *newDomain = malloc(sizeof(structDomain));
      if (newDomain != NULL) {
        newDomain->Blade = malloc(sizeof(structBlade)*elements); 
        if (newDomain->Blade != NULL) {
          newDomain->Rows = elements;
        } else {
          senderrmsg("ALLOCMEM", "Unable to allocate memory for [Domain.Blade].");
        }
      } else {
        senderrmsg("ALLOCMEM", "Unable to allocate memory for [Domain].");
      }
      return newDomain;
    }
    
    // blade.h
    // ************************************************************************** //
    // STRINGS FOR GLOBALE FILENAMES
    // ************************************************************************** //
    
    #include "globConstants.h"
    
    #ifndef BLADE_H
    #define BLADE_H
    
    typedef struct {
      int i;
      double x,y,z;
      double r, rTheta;
      double betaAngle;
    } BladeSubDomain;
    
    /* *************************************************************************** */
    
    typedef struct {
      char filename[const_strlen1]; // filename
      char idirname[const_strlen2]; // input-directory
      char odirname[const_strlen2]; // output-directory
    
      double stagger_angle;         // stagger-angle
      int blades;                   // number of blades per row
    
      BladeSubDomain LE;
      BladeSubDomain TE;
    } structBlade;
    
    /* *************************************************************************** */
    
    typedef struct {
      int Rows;                    // number of blades in Domain
      structBlade *Blade;
    } structDomain;
    
    #endif
    

    Das sollte doch genau das gleiche sein.



  • Der Fehler lautet:

    gcc -c allocmem.c
    In file included from allocmem.c:4:
    inc/allocmem.h:3: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »*« token
    allocmem.c:10: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »*« token
    


  • Deine allocmem.h musst du noch überdenken:

    1. Includeguards vergessen.
    2. Funktionsdefinitionen gehören in eine *.c Datei. In Headerdateien deklariert man üblicherweise die Prototypen der Funktionen.


  • habs gerade selbst gefunden! schön blöder Fehler!!!

    structDomain* allocateDomain(int elements) {
    


  • Noch eine letzte Frage:

    Ich würde gerne eine Funktion definieren, die diverse Fehlermeldungen meines Programms auf den Bildschirm ausgibt.

    Beispiel

    > ERROR@[MODULE]: Der Wert 2 ist größer als 1.
                      Bitte ändern Sie den Wert XYZ in der Steuerdatei ein,
    

    Ich würde die Ausgabe gerne auf zwei Funktionen (1 und 2 Zeile) aufteilen.
    1. Die erste Zeile erhält die Info, in welchem Modul der Fehler auftrat sowie den Text. Und hier stellt sich mir die Frage, wie ich der Funktion einen Text, in dem auch Zahlen "2" und "1" auftauchen, als String übergebe?

    2. Für die zweite Zeile muss der Funktion mitgeteilt werden, wieviele Tabs bzw. Leerzeichen vor dem Text stehen sollen. Wie macht man das geschickt?

    Für bessere / professionellere Vorschläge bin ich gerne offen....



  • Ich mache das z.Zt. ungefähr so:

    // msg.h
    //...
    // Include Guards nicht vergessen :D
    char* msg_mk (char*, ...);
    //...
    
    // msg.c
    #define MSGLEN_MAX 1024
    static char msgbuf[MSGLEN_MAX+1] = {0};
    
    #ifdef WIN32 
    	#define vsnprintf _vsnprintf
    #endif
    
    char* msg_mk (char* a, ...)
    {
    	const int n = MSGLEN_MAX;
    	va_list v;
    	va_start(v,a);
    	vsnprintf(msgbuf, n, a, v);
    	va_end(v); 
    	return msgbuf;
    }
    
    // main.c
    #include "msg.h"
    int main (void)
    {
    	char* e = "You have moved your mouse. Restart Windows for the "
    		"change to take effect.";
    
    	while (type = check_input())
    	{
    		switch(type)
    		{
    
    			case MOUSEMOVE:
    				puts ( msg_mk ("Error nr: %d in file %s line %d occured! "
    			"The message is: %s.\n", 88, __FILE__, __LINE__, e ));
    			exit(1);
    			break;
    
    //...
    


  • Könntest Du bitte einmal kurz erklären, was genau Du mit den Funktionen

    va_list v;
    va_start(v,a);
    vsnprintf(msgbuf, n, a, v);
    va_end(v);
    

    bewirkst. Und was ist "vsnprintf _vsnprintf" für eine Funktion?

    Ist es in C möglich optionale Parameter für eine Funktion zu definieren?



  • Phil270307 schrieb:

    Ist es in C möglich optionale Parameter für eine Funktion zu definieren?

    klar. (...) heisst, dass der aufrufer die anzahl der argumente bestimmen kann.
    http://en.wikipedia.org/wiki/Variadic_function#Variadic_functions_in_C.2C_Objective-C.2C_C.2B.2B.2C_and_D
    🙂


Anmelden zum Antworten