www.mikrocontroller.net

Forum: PC-Programmierung Zeiger in C Problem


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus Leute, ich sitze nun bereits 4 Stunden an einer dummen Aufgabe 
und immer wenn ich gedacht habe ich hätte sie hinbekommen werd ich 
entäuscht.

Mein hauptproblem liegt darin ich soll eine struktur person erstellen wo 
name, vorname und geburtstag drinn stehen.

das habe ich auch ohne probs hinbekommen. dem array habe ich dann mit 
strcpy irgenwelche Zeichen zugefügt und auf dem Bildschirm ausgegeben.

Nun soll eine Funktion geschrieben werden mit Übergabeparameter: Zeiger 
der eine Struktur von person enthält.

ich bin so vorgegangen:

#include "include files.h"
void f1 (struct person*);
void f2 (struct person*);


struct person
  {
    char firstname[20];
    char name[20];
    char birthday[20];
  };

int main (void)
{
  struct person sUserpers;

  strcpy(sUserpers.firstname, "Matthias");
  strcpy(sUserpers.name, "Knab");
  strcpy(sUserpers.birthday, "24.03.1988");
  printf("%s\n", sUserpers.firstname);
  printf("%s\n", sUserpers.name);
  printf("%s\n\n", sUserpers.birthday);

  f1(&sUserpers);
  f2(&sUserpers);

  getch();
  return 0;

}





void f1 (struct person* neu1)
{
  neu1->firstname;

  printf("Firstname:\n");
  scanf ("%s", neu1);

}





void f2 (struct person* neu1)
{
  neu1->firstname;
  printf("%s", neu1);

}


das ganze gibt mir auch das aus was ich eingetippt habe. wenn ich es 
aber nun mit weiteren funktionen erweitere für die anderen beiden arrays 
dann wird mir für alle immer nur die letzte eingabe ausgegeben.
woran liegt dass? und noch ne frage kann ich auch direkt mehrere Zeiger 
an eine Funktion übergeben? ich habe es mit kommas, &, | usw probiert 
aber es klappt irgendwie nicht.

Autor: Nico22 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau so, wie du normalerweise mehrere Variablen übergibst:

int myfunc(int a, int b);

int my_pointer_func(int *a, int *b);

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Problem liegt soweit ich es verstanden habe darin, das du nach dem 
Aufruf von f1 zwar einen neuen Namen (oder was auch imer) eingeben 
kannst, dieser aber nicht übernommen wird. Dies liegt eifnach daran das 
du bei Scanf einen pointer auf einen string (char array) benötigst. Du 
übergibst aber die Addresse auf dein ganzes struct.
scanf ("%s", neu1); //hier übergabe des pointers auf das struct
Das funktioniert solange, wie du nur auf "firstname" zugreifst, da die 
startaddresse des firstname-arrays identisch ist mit der startadresse 
des structs, bei den anderen arrays stimmt dies dann aber nicht mehr. Du 
müsstest deinen Code wie folgt anpassen.

Markus schrieb:
> void f1 (struct person* neu1)
> {
>   neu1->firstname;
>
>   printf("Firstname:\n");
>   scanf ("%s", neu1->firstname);
>   scanf("%s", neu1->name)
>
> }

Autor: sebastians (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Anweisung tut nix:
> neu1->firstname;

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sebastians schrieb:
> Diese Anweisung tut nix:
>> neu1->firstname;
Doch, sie funktioniert Einwandfrei

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal ein kurzes Testprogramm:
#include <stdint.h>
#include <stdio.h>
#include <conio.h>

struct Person{
  char firstname[20];
  char secondname[20];
};

void f1(struct Person* bla){
  printf("Bitte firstname eingeben: \n");
  scanf("%s",bla->firstname);
  printf("Bitte secondname eingeben:\n");
  scanf("%s", bla->secondname);
}

void f2(struct Person* bla){
  printf("Firstname");
  printf(bla->firstname);
  printf("\n");
  printf("Second Name:");
  printf(bla->secondname);
  getch();

}
int main(void){
  struct Person Erster;

  f1(&Erster);
  f2(&Erster);
  return 0;
}



Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nico22 schrieb:
> int my_pointer_func(int *a, int *b);

schon probiert und da kommt halt eben ein fehler:

Unbehandelte Ausnahme bei 0x5dbbde8f (msvcr100d.dll) in Aufgabe 4.exe: 
0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000014.

und er zeigt auf die zeile:

*(char *)pointer = (char)ch;
                                    pointer = (char *)pointer + 1;

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
alles klar hab meinen fehler. ich hab die ganze zeit unterschiedliche 
namen in den übergabewert für den zeiger reingeschrieben. hätte nicht 
gedacht dass es nur mit einem funktioniert.

danke an alle.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> Nico22 schrieb:
>> int my_pointer_func(int *a, int *b);
>
> schon probiert und da kommt halt eben ein fehler:
>
> Unbehandelte Ausnahme bei 0x5dbbde8f (msvcr100d.dll) in Aufgabe 4.exe:
> 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000014.
>
> und er zeigt auf die zeile:
>
> *(char *)pointer = (char)ch;
>                                     pointer = (char *)pointer + 1;

Dann steckst dsu falsche POinter in die Funktion hinein.
Ausserdem ist es ziemlich witzlos, über Code zu spekulieren, den man 
nicht kennt.

Ausserdem: Was sollen die Casts da?
Wenn du Pointer umcasten musst (mit deinem jetzigen Wissensstand), dann 
machst du mit Sicherheit einen schweren Fehler.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Antwort schrieb:
> sebastians schrieb:
>> Diese Anweisung tut nix:
>>> neu1->firstname;
> Doch, sie funktioniert Einwandfrei

Ich würde (bei Deinem Kenntnisstand) solche Hinweise nicht einfach 
wegwischen.  Diese Anweisung tut nämlich wirklich nichts.

Dann solltest Du bei Deinem Compiler alle Warnings einschalten (-Wall 
beim gcc).  Und die Warnungen, die dann kommen, auch nicht ignorieren. 
Denn sowohl Deine Argumente für printf als auch scanf in den 
Unterfunktionen im Originalcode sind oberfaul.  Da muss etwas kommen. 
Und hilfreiche Hinweise müssen auch ausgegeben werden.

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die einzigen Warnungen die ich erhalte (Visual Studio 2008) besagen das 
scanf als unsicher deklariert wurde und man stattdessen lieber scanf_s 
verwenden soll (um buffer overflows zu verhindern).

Dann kläre mich mal auf was genau mein Fehler sein soll. Würde mich 
jetzt schon interessieren.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe nix umgecastet. diese fehlermeldung zeigt ja nicht mal in 
meinen code sondern in einen anderen von vusial studio . wie man 
eigentlich auch sieht da mein code ja oben steht.

weiß jetzt grad nicht mehr wie der code heißt da der fehler ja weg ist.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Antwort schrieb:
> Dann kläre mich mal auf was genau mein Fehler sein soll.

Gerne.  Das Argument ist beide Male „neu1“.  Das ist vom Typ „struct 
person *“.  Da der Formatstring „%s“ lautet, wird aber ein „char *“ 
benötigt.  Nochmal eine der beiden Fehlerstellen:
void f1 (struct person* neu1)
{
  neu1->firstname;                   // Tut nichts

  printf("Firstname:\n");
  scanf ("%s", neu1);                // struct person * bei %s

}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:

> meinen code sondern in einen anderen von vusial studio . wie man
> eigentlich auch sieht da mein code ja oben steht.

Dein Code da oben gilt schon lange nichts mehr, weil du ihn in der 
Zwischenzeit ja verändert hast.

Und selbst wenn, passt dein Code mit dem hier, das du als Vorgabe für 
deine Frage benutzt hast
> >> int my_pointer_func(int *a, int *b);
>
> schon probiert und da kommt halt eben ein fehler:

in keinster Weise zusammen

> weiß jetzt grad nicht mehr wie der code heißt da der fehler ja weg ist.

Das heißt nicht viel.
Durch Testen kann man immer nur das Vorhandensein von Fehlern 
nachweisen, nie das Fehlen. Nur weil ein Code nicht gleich abstürzt, 
heißt das noch lange nicht, das er fehlerfrei ist.

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:
> Gerne.  Das Argument ist beide Male „neu1“.  Das ist vom Typ „struct
> person *“.  Da der Formatstring „%s“ lautet, wird aber ein „char *“
> benötigt.  Nochmal eine der beiden Fehlerstellen:
Falsch, in meinen Beispielen wird beides mal ein char pointer übergeben. 
Nämlich z.B. neu1->firstname. Da firstname ein char array ist erhält man 
durch Angabe des arraynamens ohne weitere klammern oder sonstiges den 
pointer darauf. Es ist identisch zu &(neu1->firstname[0])

Sieh dir meinen  Post von 22:13 Uhr noch einmal genau an.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann mir bitte nochmal jemand helfen? sitze nun schon seit etlichen 
stunden an der nächsten aufgabe. habe sie nach skript geschrieben und 
auch mal in das buch "c von a bis z" reingeschaut nur werd ich daraus 
nicht wirklich schlau.

und zwar soll ich mehrdimensionale arrays an eine funktion übergeben. 
das klappt auch wunderbar. nur muss ich bei zahlen die kleiner 10 sind 
eine 0 vorschieben. dies habe ich mit einer if abfrage gemacht nur 
klappt es nie egal was ich mache.

kann mir jemand nochmal kurz helfen kann ja eigentlich nicht so viel 
falsch sein. der wert wird ja übergeben.


#include "include files.h"

void f1 (int iy, int ix, int aZahlen[10][10]);

int main (void)
{
    int aZahlen [10][10];
    printf("Zahl eingeben: ");
    scanf("%s", &aZahlen[0][0]);
    f1(0, 0, aZahlen);
    getch();
}

void f1 (int iy, int ix, int aZahlen[10][10])
{
  if (aZahlen[0][0] >= 1)
    {
      printf("%s", aZahlen);
    }
    else
    {
      printf("0%s", aZahlen);
    }
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:

>     int aZahlen [10][10];

>     scanf("%s", &aZahlen[0][0]);

Ähm.
Seit wann ist denn %s das korrekte Formatzeichen für einen int?

Detto
     printf("%s", aZahlen);

Da ist es sogar noch schlimmer.
aZahlen ist ein ganzes Array, also viele int. Genau genommen 10 * 10 
also 100 Stück. Und die willst du alle mit einem popeligen %s, der für 
Strings gedacht ist ausgeben.

Nochmal zurück an den Anfang, 3. oder 4. Stunde und nachsehen, welche 
Formatierzeichen es gibt, wann und wo sie verwendet werden müssen.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Antwort schrieb:
> Falsch, in meinen Beispielen wird beides mal ein char pointer übergeben.

Ja, da bin ich ducheinandergekommen, wer was schrieb.  Wie ich aber 
ebenfalls schrieb, bezieht sich das mit dem char * auf das 
Originalposting.  Und in meiner anderen Antwort habe ich das sogar 
zitiert, es wäre somit unschwer erkennbar gewesen, auf was ich mich 
bezog.

Für Dich war das „tut nichts“:

Antwort schrieb:
> sebastians schrieb:
>> Diese Anweisung tut nix:
>>> neu1->firstname;
> Doch, sie funktioniert Einwandfrei

Du schriebst darauf „Doch, sie tut einwandfrei“.  Ohne das „Doch“ wäre 
das noch angegangen, denn natürlich tut das einwandfrei - nichts.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ähm.
> Seit wann ist denn %s das korrekte Formatzeichen für einen int?

he danke man ohne flax. hatte vorher schon %d drinn stehn dacht aber 
dass es nicht stimmen kann weil dann werte von über 200000 immer da 
standen und mit %s wurde mir das richtige ausgegeben.

auf jedenfall scheint es so dass als ich %d am anfang benutzt habe noch 
was falsch war und es mir deshalb so einen mist ausgegeben hat. 
mittlerweile funktioniert das ganze.

es sind immer die kleinen dinge die einem kopfzerbrechen bereiten.

Autor: DirkB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus schrieb:
> hatte vorher schon %d drinn stehn dacht aber
> dass es nicht stimmen kann weil dann werte von über 200000 immer da
> standen und mit %s wurde mir das richtige ausgegeben.

über 200000 war dann die Adresse von aZahlen.

Mit    scanf("%s", &aZahlen[0][0]); hast du Die Zahl als Text (String) 
eingelesen und ab aZahlen abgelegt.
Mit  printf("%s", aZahlen); hast du den String wieder ausgegeben.
Denn &aZahlen[0][0] == aZahlen

Autor: Antwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:
> Antwort schrieb:
>> Falsch, in meinen Beispielen wird beides mal ein char pointer übergeben.
>
> Ja, da bin ich ducheinandergekommen, wer was schrieb.  Wie ich aber
> ebenfalls schrieb, bezieht sich das mit dem char * auf das
> Originalposting.  Und in meiner anderen Antwort habe ich das sogar
> zitiert, es wäre somit unschwer erkennbar gewesen, auf was ich mich
> bezog.
>
Achso, das klärt natürlich alles auf.
> Für Dich war das „tut nichts“:
>
> Antwort schrieb:
>> sebastians schrieb:
>>> Diese Anweisung tut nix:
>>>> neu1->firstname;
>> Doch, sie funktioniert Einwandfrei
>
> Du schriebst darauf „Doch, sie tut einwandfrei“.  Ohne das „Doch“ wäre
> das noch angegangen, denn natürlich tut das einwandfrei - nichts.

Und meine Aussage war auf mein Beispiel bezogen, nicht auf das original. 
Da haben wir aneinander vorbei geredet.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, alles klar.  Also beidseitige Verwechslung :-).  Passiert mal.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.