[GELÖST] C Probleme mit Struct und Modulen

Übersicht Sonstiges Smalltalk

Neue Antwort erstellen

 

CO2

ehemals "SirMO"

Betreff: [GELÖST] C Probleme mit Struct und Modulen

BeitragDi, Apr 24, 2012 16:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,
Ich habe ein Problemchen: Ich habe 3 Dateien erstellt, erstmal der Code:
main.c Code: [AUSKLAPPEN]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "konto.c"

int main()
{
    struct Account Dingens;
    create_acc(Dingens, "Marius", "O.", 0.0, 101);

    printf("%s", Dingens.Nachname);
    return 0;
}


konto.h Code: [AUSKLAPPEN]
#ifndef KONTO_H
#define KONTO_H
#endif

struct Account
{
    char Vorname[30];
    char Nachname[20];
    float Kontostand;
    unsigned int Kontonummer;
};

void create_acc(struct Account, char*, char*, float, int);


konto.c Code: [AUSKLAPPEN]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "konto.h"

void create_acc(struct Account Konto, char VorName[30], char NachName[20], float KontoStand, int KontoNummer)
{
    strcpy(Konto.Vorname, VorName);
    strcpy(Konto.Nachname, NachName);
    Konto.Kontostand = KontoStand;
    Konto.Kontonummer = KontoNummer;
}


So, nun das Problem: Wenn ich versuche die main.c zu compilen, dann gibt CodeBlocks folgende Fehler zurück: Zitat:
-> multiple definition of 'create_acc' (Line 7)
-> first defined here (Line 7)

Beide Fehler entstammen der konto.c

Kann mir wer helfen?
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti
  • Zuletzt bearbeitet von CO2 am Mi, Apr 25, 2012 16:12, insgesamt einmal bearbeitet

ZEVS

BeitragDi, Apr 24, 2012 16:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Code: [AUSKLAPPEN]
#ifndef KONTO_H
#define KONTO_H
#endif

Das letzte endif kommt nach den Definitionen. Das ist der Sinn der ganzen Sache.

ZEVS
 

CO2

ehemals "SirMO"

BeitragDi, Apr 24, 2012 16:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, habe das nun geändert, allerdings bleiben die Fehler bestehen.
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

ZEVS

BeitragDi, Apr 24, 2012 16:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Anscheinend erkennt der Compiler einen Unterschied zwischen
Zitat:
void create_acc(struct Account, char*, char*, float, int);

und
Zitat:
void create_acc(struct Account Konto, char VorName[30], char NachName[20], float KontoStand, int KontoNummer)

, sodass er den Fehler ausgibt. Hierfür kämen eigentlich nur die char-Parameter in Frage.
Vielleicht hilft es ja, wenn du die Parameter exakt gleich definierst.

ZEVS

the FR3AK

BeitragDi, Apr 24, 2012 17:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Sollte man nicht die *.h Datei includen anstatt der *.c ?
 

c64

BeitragDi, Apr 24, 2012 19:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Schon mal drüber nachgedacht das C gar keine keine Überladung/Polymorphie unterstützt Wink !

Und das was the FR3AK da geschrieben hat sollte man ggf. auch berücksichtigen! Zwar nicht zwingend, aber wenn du es richtig machen möchtest wäre das mal eine Überlegung wert Wink !

mfg.


Is aber auch niedlich hat C in der Signatur und noch nichtmal Grundkenntnisse so ein Poser Smile ! (nich böse gemeint !!!!!!)
Betreten verboten! Kinder haften für ihre Eltern!
  • Zuletzt bearbeitet von c64 am Di, Apr 24, 2012 19:31, insgesamt 2-mal bearbeitet

Noobody

BeitragDi, Apr 24, 2012 19:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Zum ersten: Dein Includeguard im Header stimmt nicht - das #endif muss ans Ende der Datei. In diesem Fall spielt das aber keine Rolle, da du in einer Übersetzungseinheit die konto.h nicht mehrmals einbindest.
Trotzdem sollte man sich aber angewöhnen, richtige Includeguards zu schreiben (oder benutz #pragma once, das wird von den meisten Compilern unterstützt).

Zum zweiten: Du bindest konto.c ein. Das bringt schon mal viele Probleme mit sich, und ich schätze mal schwer, dass es hier auch der Übeltäter ist.
Leider sieht man aus deiner Fehlermeldung nicht, ob es ein Linker- oder ein Compilerfehler ist, und ich kenne mich auch nicht mit Codeblocks aus, aber ich vermute mal folgendes:

- Du hast in Codeblocks ein Projekt erstellt und sowohl konto.c als auch main.c hinzügefügt
- Codeblocks behandelt Projekte wie die meisten IDEs und kompiliert bei einem Build alle geänderten Dateien einzeln und linkt sie dann zusammen
- Dein geposteter Fehler kommt vom Linker

In diesem Fall passiert nämlich folgendes: Codeblocks kompiliert main.c und konto.c. Die erstellte konto.o enthält dann die Funktionsdefinition von create_acc (ein sogenanntes "strong symbol").
Beim Kompilieren der main.c sieht der Preprocessor das #include "konto.c" und copypasted die konto.c in deine main.c. Zwar bindet konto.c die konto.h ein, welche die Vorwärtsdeklaration von create_acc enthält (eine Funktionsdeklaration, d.h. ein "weak symbol"), aber da du trotzdem die ganze konto.c einbindest, hast du gleichzeitig die Funktionsdefinition von create_acc drin (nochmal ein "strong symbol").

Codeblocks linkt dann frischfröhlich konto.o und main.o zusammen, nur dass dann der Linker zwei strong symbols für create_acc findet - und eine Fehlermeldung wirft.

Der Fix wäre dann, nur konto.h einzubinden - dann hast du beim linken nur eine Definition von create_acc und die Sache sollte glattlaufen.
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun
 

CO2

ehemals "SirMO"

BeitragMi, Apr 25, 2012 16:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, habe es nun überarbeitet, hier die entsprechenden Codes:

main.c Code: [AUSKLAPPEN]
#include <stdio.h>
#include <stdlib.h>
#include "konto.h"

int main()
{
    int iEingabe;
    int IDCounter = 100;
    int KontoID;
    int KontoID2;
    float Amount;
    while(1)
    {
        printf("### MENUE ###\n");
        printf("(1) Konto erstellen\n");
        printf("(2) Konto anzeigen\n");
        printf("(3) Konto loeschen\n");
        printf("(4) Ueberweisung\n");
        printf("(0) Beenden\n\n\n");

        printf("Auswahl: "); scanf("%d", &iEingabe);
        switch(iEingabe)
        {
            case 0:
                return 0;
                break;
            case 1:
                create_acc(IDCounter);
                IDCounter++;
                break;
            case 2:
                printf("Geben sie die Kontonummer an: "); scanf("%d", &KontoID);
                show_acc(KontoID);
                break;
            case 3:
                printf("Geben sie die Kontonummer an: "); scanf("%d", &KontoID);
                kill_acc(KontoID);
                break;
            case 4:
                printf("Geben sie die Kontonummer an, von der abgebucht werden soll: "); scanf("%d", &KontoID);
                printf("Geben sie die Kontonummer an, an die ueberwiesen werden soll: "); scanf("%d", &KontoID2);
                printf("Geben sie den Betrag an, der ueberwiesen werden soll: "); scanf("%f", &Amount);
                transfer(KontoID, KontoID2, Amount);
                break;
            default:
                break;
        }
    }
    return 0;
}


konto.h Code: [AUSKLAPPEN]
#ifndef KONTO_H
#define KONTO_H
struct account
{
    char Vorname[20];
    char Nachname[30];
    float Kontostand;
    unsigned int Kontonummer;
}Accounts[1000];
void create_acc(int);
void kill_acc(int);
void show_acc(int);
void transfer(int, int, float);
#endif


konto.c Code: [AUSKLAPPEN]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "konto.h"

void create_acc(int ID)
{
    printf("\n\nVorname:     "); scanf("%s", Accounts[ID].Vorname);
    printf("Nachname:    "); scanf("%s", Accounts[ID].Nachname);
    printf("Kontostand:  "); scanf("%f", &Accounts[ID].Kontostand);
    printf("Kontonummer: %d\n", ID);
    Accounts[ID].Kontonummer = ID;
    printf("Kontenerstellung erfolgreich!\n\n\n");
}

void kill_acc(int ID)
{
    strcpy(Accounts[ID].Vorname, "\0");
    strcpy(Accounts[ID].Nachname, "\0");
    Accounts[ID].Kontostand = 0;
}

void show_acc(int ID)
{
    if(strlen(Accounts[ID].Vorname) == 0 || strlen(Accounts[ID].Nachname) == 0)
    {
        printf("\n\nDieses Konto ist noch nicht belegt\n\n\n");
    }
    else
    {
        printf("\n\nVorname:     %s\n", Accounts[ID].Vorname);
        printf("Nachname:    %s\n", Accounts[ID].Nachname);
        printf("Kontostand:  %.2f\n", Accounts[ID].Kontostand);
        printf("Kontonummer: %d\n\n\n", Accounts[ID].Kontonummer);
    }
}

void save_acc(int ID)
{
    FILE *Datei;
    Datei = fopen("Konten.txt", "a+");
    fprintf(Datei, "Kontonummer: %d\nVorname:     %s\nNachname:    %s\nKontostand:  %.2f\n\n", Accounts[ID].Kontonummer, Accounts[ID].Vorname, Accounts[ID].Nachname, Accounts[ID].Kontostand);
    fclose(Datei);
}

void transfer(int fromID, int toID, float amount)
{
    if(Accounts[fromID].Kontostand - amount < 0)
    {
        printf("\n\nLeider nicht moeglich!\n\n");
    }
    else
    {
        Accounts[fromID].Kontostand = Accounts[fromID].Kontostand - amount;
        Accounts[toID].Kontostand = Accounts[toID].Kontostand + amount;
        printf("\n\nTranfer erfolgreich!\n\n");
    }
}


ich danke für die Hilfe
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Neue Antwort erstellen


Übersicht Sonstiges Smalltalk

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group