Ansi C Pointer Array Problem

Talinsei

Cox Orange
Registriert
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
 

FrankR

Gascoynes Scharlachroter
Registriert
15.11.07
Beiträge
1.537
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.
 

Der Paule

Königsapfel
Registriert
26.05.07
Beiträge
1.199
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
 

Gogul

Uelzener Rambour
Registriert
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
 

Talinsei

Cox Orange
Registriert
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]);
	}
	
	
}
 
Zuletzt bearbeitet:

FrankR

Gascoynes Scharlachroter
Registriert
15.11.07
Beiträge
1.537
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...
 

Talinsei

Cox Orange
Registriert
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?
 

Der Paule

Königsapfel
Registriert
26.05.07
Beiträge
1.199
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
 

Poljpocket

Salvatico di Campascio
Registriert
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
 

Talinsei

Cox Orange
Registriert
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?
 

FrankR

Gascoynes Scharlachroter
Registriert
15.11.07
Beiträge
1.537
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.
 

Talinsei

Cox Orange
Registriert
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.
 

FrankR

Gascoynes Scharlachroter
Registriert
15.11.07
Beiträge
1.537
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...
 

Talinsei

Cox Orange
Registriert
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
 

karolherbst

Danziger Kant
Registriert
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.
 

Talinsei

Cox Orange
Registriert
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 ...
 

below

Purpurroter Cousinot
Registriert
08.10.06
Beiträge
2.858
Offenbar fehlt Dir ein

#include <stdio.h>

Alex
 

karolherbst

Danziger Kant
Registriert
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