1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Ansi C Pointer Array Problem

Dieses Thema im Forum "OS X-Developer" wurde erstellt von Talinsei, 06.01.10.

  1. Talinsei

    Talinsei Cox Orange

    Dabei seit:
    01.09.09
    Beiträge:
    98
    Hallo, ich habe ein Problem bei der richtigen Anwendung von Pointern und Array's unter Ansi C
    Im ersten schritt lasse ich einpaar Zahlen einlesen:

    Aufruf :

    int arraysize=20;
    int num[arraysize];

    einlesen(&arraysize,&num);

    Funktion :
    void einlesen(int *arraysize, int *num) {

    FILE *datei;
    const int ANZAHL = *arraysize, LAENGE=5;
    char line[ANZAHL][LAENGE];
    int buffer;
    int i=0,error=0;
    datei = fopen ("/Users/Tim/Documents/Praktikum 6/sort.dat","r+");
    if (datei != NULL)
    {
    while ((!feof(datei))&&(error==0)) {


    fgets(line,LAENGE,datei);

    buffer=atoi(line);
    num = buffer;


    i++;
    if(i==*arraysize) { error=1;}

    }
    } else {printf("Öffnen Fehlgeschlagen");}

    }

    -----------------------------------------------------------------

    Das klappt meiner Meinung nach auch. Jetzt möchte ich das Array in einer anderen Funktion wieder ausgeben.


    Aufruf :

    ausgeben(&num,&arraysize);

    Funktion :


    void ausgeben(int *arraysize, int *num) {
    int i=0;
    do {
    printf (" %i \n",*num);
    i++;
    } while(i<*arraysize) ;
    }


    -------------------------------------------------------------

    Egal wie ich es drehe oder wende, es kommt immer nur Zahlenmüll raus. Als ob der Pointer auf Stellen zeigt, die es nicht gibt. Jemand ne Idee wodran das liegt? Wird das Array vielleicht in der ersten Funktion nicht ordnungsgemäß gefüllt ?

    Grüße Tim
     
  2. FrankR

    FrankR Johannes Böttner

    Dabei seit:
    15.11.07
    Beiträge:
    1.158
    Schau doch mal mit dem Debugger schritt für schritt nach, was da stattfindet, hat sicher einen bessern Lerneffekt, als wenn DIr hier jemand sagt, was Du falsch machst. Auf den ersten Blick, erscheint mir in der Ausgabe *num nicht so ganz richtig, denke mal num trifft es vielleicht eher.

    Ganz abgesehen davon, dass Du, wenn Du ernsthafter in C einsteigen willst und das nicht nur als Pflichtaufgabe hast, dich mal mit Deinem Code-Sil auseinandersetzen solltest - ich empfehle nach wie vor den K&R als Klassiker zum Thema.
     
  3. Der Paule

    Der Paule Königsapfel

    Dabei seit:
    26.05.07
    Beiträge:
    1.200
    Hey,

    zu aller erst. Die Array-Größe musst du nicht als Pointer übergeben. Zweitens, ist die Reihenfolge beim Aufruf der Ausgeben-Funktion falsch. Beachtest du diese Dinge, klappt der Aufruf. Ein Tipp, nutze die for-Scheife anstatt die while-Schleife, ist wesentlich bequemer und einfacher :)

    Hier mal ein Beispielcode mit deinem Code, der bei mir Funktioniert:

    Code:
    #include <iostream>
    
    void ausgeben(int arraysize, int *num) 
    {
    int i=0;
    do 
    {
    printf (" %i \n",num[i]);
    i++;
    } while(i<arraysize) ;
    }
    
    void einlesen(int arraysize, int *num) 
    {
    FILE *datei;
    const int ANZAHL = arraysize, LAENGE=5;
    char line[ANZAHL][LAENGE];
    int buffer;
    int i=0,error=0;
    datei = fopen ("/Users/daniel/Desktop/sort.dat","r+");
    if (datei != NULL)
    {
    while ((!feof(datei))&&(error==0)) 
    {
    fgets(line[i],LAENGE,datei);
    
    buffer=atoi(line[i]);
    num[i] = buffer;
    
    i++;
    if(i==arraysize) 
    { error=1;}
    }
    }
    else {printf("Öffnen Fehlgeschlagen");
    }
    }
    
    int main (int argc, char * const argv[]) 
    {
        int arraysize=20;
        int num[arraysize];
        
        einlesen(arraysize,num);  
        ausgeben(arraysize,num);
        
        return 0;
    }
    
    
    mfg
    paule
     
  4. Gogul

    Gogul Uelzener Rambour

    Dabei seit:
    21.05.04
    Beiträge:
    372
    Hi!

    Was mir auf den ersten Blick auffällt:

    Code:
    einlesen(&arraysize,&num);
    wird zu
    Code:
    einlesen(&arraysize,num);
    oder
    Code:
    einlesen(&arraysize,&num[0]);
    da ein array automatisch zu einem pointer zerfällt!

    Die Größe eines arrays macht legt man auch über #define fest, da man die Größe von arrays nur mittels malloc zur Laufzeit verändern/erstellen kann!

    Dann kannst du auch einfach mittles des Debuggers schauen was denn in dein Array geschrieben wird!

    Auch beim einlesen klappt glaub ich noch was nicht. Mein tipp als top C buch: C von A bis Z
     
  5. Talinsei

    Talinsei Cox Orange

    Dabei seit:
    01.09.09
    Beiträge:
    98
    Danke für eure Tipps, habe jetzt ein paar Sachen versucht :

    Wenn ich einfach nur

    Code:
    ausgeben(num,arraysize);
    übergebe und per

    Code:
    void ausgeben(int arraysize, int num) {
    printf (" %i \n",num);
    
    klappt es. Wird halt eben nur eine Zahl übergeben. Das gibt mir immerhin schonmal die Gewissheit, dass in dem Array was drinsteht.

    Wenn ich allerdings das ganze mit

    Code:
    void ausgeben(int arraysize, int *num) {
    printf (" %i \n",num[0]);
    
    annehme, sagt er mir nur

    "Segmentation fault"

    Habe mir alle logisch erscheinenden Kombinationen durch. Ich mag jetzt schon keine Pointer mehr sehen ;).

    Grüße Tim


    *edit habs glaube ich.

    Code:
    ausgeben(num,arraysize); 
    
    void ausgeben(int *num,int arraysize) {
    	
    	for(int i=1;i<arraysize;i++) {
    		printf (" %i \n",num[i]);
    	}
    	
    	
    }
    
    
     
    #5 Talinsei, 06.01.10
    Zuletzt bearbeitet: 06.01.10
  6. FrankR

    FrankR Johannes Böttner

    Dabei seit:
    15.11.07
    Beiträge:
    1.158
    Wie schon gesagt, kann Dir nur raten dich mal etwas mit dem gdb zu befassten, den Fehler hättest Du da in ein paar Sekunden gesehen.

    Mich wundert auch, dass Dir der Compiler bei dem Aufruf falsch herum keine Warnings an den Kopf geworfen hat...
     
  7. Talinsei

    Talinsei Cox Orange

    Dabei seit:
    01.09.09
    Beiträge:
    98
    ich hab nen neues problem. Ich habe in der Main Funktion eine Variable deklariert.

    Int Anzahl; jetzt übergebe ich diese Variable an eine Funktion

    insert(num,arraysize,&anzahl);

    in der Funktion insert, wird diese Variable inkrementiert.

    int insert(int *num, int arraysize, int *anzahl) {

    *anzahl++;
    }

    Wenn ich die Variable in der Insert funktion ausgeben, steht auch der neue richtige Wert drin.

    Rufe ich jetzt eine andere Funktion auf, in der ich mit dieser Variablen arbeiten möchte, steht aber immernoch der alte Wert drin. Jemand ne Ahnung wodran das liegen könnte?
     
  8. Der Paule

    Der Paule Königsapfel

    Dabei seit:
    26.05.07
    Beiträge:
    1.200
    Ja. Weil es keine globale Variable ist. Eine globale Variable ist im ganzen Projekt, egal in welcher Funktion gültig und hat immer den gesetzten Wert. Du nutzt eine lokale Variable. D.h. sie ist nur dort gültig wo du sie deklariert hast. D.h. die Anzahl in der Main ist jeweils eine lokale Variable und nur in der Main gültig. Und die in der Funktion auch eine eigene lokale Variable. Diese ist dann NUR in der Funktion gültig. Entweder gibts du den Anzahl-Wert zurück an die Main und reichst ihn weiter. Da du aber immer nur einen Rückgabe-Wert haben kannst denke ich mal, gilt diese Lösung bei dir nicht. Also musst du die Anzahl global deklarieren.

    mfg
    paule
     
  9. MacApple

    MacApple Lord Grosvenor

    Dabei seit:
    05.01.04
    Beiträge:
    3.470
    So incrementierst Du den Zeiger, nicht den Wert, auf den er zeigt. Der ++ Operator wird vor dem *-Operator angewendet. Es fehlen Klammern:
    Code:
    (*anzahl)++
    MacApple
     
  10. Poljpocket

    Poljpocket Salvatico di Campascio

    Dabei seit:
    07.01.07
    Beiträge:
    432
    Du solltest am Besten mal eine gründliche Einführung in C lesen und dich dann nochmal mit dem Projekt hier befassen. Vorallem solltest du dir mal das Kapitel mit den Pointern genau durchlesen, denn wie ich sehe, hast du da noch einige Probleme mit, nicht wahr?

    Gruss ppocket
     
  11. Talinsei

    Talinsei Cox Orange

    Dabei seit:
    01.09.09
    Beiträge:
    98
    Ja, ich schau mir das am besten nochmal an. Wie kann ich die einzlenen Funktionen jetzt auslagern?

    Ich erstelle zum Beispiel eine Header und eine C
    Code:
    #ifndef funktions_H
    #define funktions_H
    
    #include "funktion.c"
    
    int suchen(int *num, int anzahl);
    int delete(int *num, int anzahl);
    int insert(int *num, int anzahl);
    void sort(int *num, int anzahl);
    void ausgeben(int *num, int *anzahl);
    void einlesen(int *num, int arraysize,int *anzahl);
    
    
    
    #endif /* funktion_H */
    [\CODE]
    
    und setzte die Funktionen in die entsprechende  funktion.c datei.
    
    Danach habe ich die Header datei in der Main datei includet und versucht diese auszuführen. Klappt aber die function.c strotzt nur so vor fehler. Die ganzen Standard Library's sind nicht verfügbar. Habt ihr dazu nen anschauliches Beispiel, bzw nen bissel was zu Lesen?
     
  12. FrankR

    FrankR Johannes Böttner

    Dabei seit:
    15.11.07
    Beiträge:
    1.158
    Wenn Du es ernsthaft angehehen lassen willst, fang mit der Bibel an: K & R. Gibt es sicher auch noch irgendwo auf deutsch.

    Falls Du es nicht ernsthaft angehen lassen willst, halte ich es nicht für sinnvoll sich mit C/C++/Objective C & Konsorten zu beschäftigen. Um mal in die Programmierung reinzuschnuppern und die Basics zu lernen ist eine Scriptsprache wie Ruby/Python/usw. sicher interessanter.

    Trial & Error halte ich nicht für sehr effizient, wenn man nicht die Grundlangen erst mal drauf hat.
     
  13. Talinsei

    Talinsei Cox Orange

    Dabei seit:
    01.09.09
    Beiträge:
    98
    ja, es handelt sich leider um ein Schulprojekt, da fragt mich keiner ob ich lieber eine Scriptsprache lernen würde. Vogel friss oder stirb.
     
  14. FrankR

    FrankR Johannes Böttner

    Dabei seit:
    15.11.07
    Beiträge:
    1.158
    Ok, da kann man wohl nichts machen - halte es aber im Jahr 2010 etwas unsinnig C für Schulprojekte einzusetzen... Wenn Du da weiter machen willst, kann ich Dir trotzdem nur den K&R ans Herz legen.

    Wenn Dir hier geholfen werden soll, dann hilft es *vollständigen* Code zu posten, inkl. Fehlermeldungen, "strotz nur so vor Fehlern" kann alle möglichen Gründe haben, und wenn's nur ein falsches Semikolon ist...
     
  15. Talinsei

    Talinsei Cox Orange

    Dabei seit:
    01.09.09
    Beiträge:
    98
    Hatte da nen paar, Fehler drin. Bekomme jetzt noch eine Fehlermeldung :

    ld: duplicate symbol _suchen in /Users/Tim/Documents/Aufgabe 8/build/Aufgabe 8.build/Debug/Aufgabe 8.build/Objects-normal/x86_64/function.o and /Users/Tim/Documents/Aufgabe 8/build/Aufgabe 8.build/Debug/Aufgabe 8.build/Objects-normal/x86_64/main.o

    Das heißt ja sicher soviel wie das _suchen doppelt ist. Isses aber nicht o_O
     
  16. below

    below Kalterer Böhmer

    Dabei seit:
    08.10.06
    Beiträge:
    2.865
    Isses aber doch. ld lügt nicht.

    Alex
     
  17. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    doch ist es. man included in einem Header nicht den Code. Somit deklarierst du die Funktion mit den Anweisungen und danach, deklarierst du sie nochmal, diesmal aber ohne Anweisungen. Ich würde an deiner Stelle es andersherum machen, da du später, wenn du objektorientiert schreiben solltest, nur den Header eines Objektes includest und nicht die gesamte Objekt-Klasse.

    EDIT: nochmal mit Beispiel:
    du sagst zuerst zb "int addieren(int a,int b){ return a+b;}". Dann im späteren code steht nochmal "int addieren (int a,int b);" also ist es 2 mal definiert.

    Zweitens included man normalerweise Standartbibliotheken immer im Header. Das macht vieles einfacher (finde ich).

    Ich kann mich meinen Vorrednern nur anschließen. Ließ dir zuerst mal ein vernünftiges C Buch durch. Mir ist auch mal vorgekommen, dass mein Informatiklehrer eigentlich keine Ahnung von dem hat, was er unterrichtet.
     
  18. Talinsei

    Talinsei Cox Orange

    Dabei seit:
    01.09.09
    Beiträge:
    98
    Okay, ich habe jetzt also die Header datei :

    Code:
    #ifndef functions_h
    #define functions_h
    
    #include <stdlib.h>
    #include <stdio.h>
    
    
    
    
    int suchen(int *num,int anzahl);
    int deletef(int *num, int anzahl);
    int insert(int *num, int anzahl);
    void sort(int *num, int anzahl);
    void ausgeben(int *num, int *anzahl);
    void einlesen(int *num, int arraysize,int *anzahl);
    
    #endif /* function_h */
    
    Dann meine function.c datei:

    Code:
    #include "function.h"
    
    int suchen(bla....) {
    
    }
    
    ...
    
    und meine main datei :

    Code:
    #include "function.h"
     
    int main() { 
      suchen(bla....);
    }
    

    http://s3.directupload.net/file/d/2035/bwg7jjg3_png.htm <-- Fehler

    ich hasse es ...
     
  19. below

    below Kalterer Böhmer

    Dabei seit:
    08.10.06
    Beiträge:
    2.865
    Offenbar fehlt Dir ein

    #include <stdio.h>

    Alex
     
  20. karolherbst

    karolherbst Danziger Kant

    Dabei seit:
    11.05.07
    Beiträge:
    3.878
    mhh warum ist #endif /* function_h */ hier function_h auskommentiert (oder ich komme hier grade mit make durcheinander :D, ne ist schon richtig so, falscher Gedanke)?, naja auch egal, wie below schon sagte, mal ein #include <stdio.h> noch in die main.c
     

Diese Seite empfehlen