Forum: PC-Programmierung Zufallstexte


von M. T. (yohojoe)


Lesenswert?

So hallo erstmal,

ich sitz hier schon stunden lang vor einer mir gestellten aufgabe in 
informatik (c#). Anhängend einer kleiner teil der aufgabenstellung der 
mir ziemlich schwer fällt.

http://s14.directupload.net/images/130403/b8ak6k95.png

schritt 1 lässt sich ziemlich einfach bewältigen: (nur relv. 
codestellen)
1
#define MAXLEN 5
2
srand(time(NULL));
3
int rdmnum = rand() % MAXLEN +1;


schritt 2: soweit ich es verstanden habe sollen in diesem puffer eine 
zufällige anzahl zufälliger buchstaben zusammengeführt werden (in einem 
späteren teil der aufgabe werden diese im puffer stehenden zeichenketten 
in ein array übernommen).

Dafür brauche ich den memory allocation befehl (malloc) und ich muss 
wissen wie groß der reservierte speicher sein soll: (maximale länge der 
zeichenkette + 2 zeichen für die terminierung die meines wissen so 
aussieht: \0)
1
char *puffer;
2
    puffer = (char*) malloc (MAXLEN+2);

schritt 3: hier setzt es bei mir aus da ich die aufgabenstellung gar 
nicht verstehe. Um wenigstens etwas vorran zu kommen habe ich die 
zufallsbuchstaben nochmal als eigenen "zufallsgenerator" geschrieben:

1
char rdmchar = 64 + (rand() % CHAR +1);

dieser gibt mir also die buchstaben A-Z zufällig aus

schritt 4: ??


mein ganzer code sieht mom. so aus:
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <time.h>
4
#include <string.h>
5
#define MAXLEN 5
6
#define CHAR 26
7
#define CHARCNT 10
8
9
int main()
10
{
11
12
 1   srand(time(NULL));
13
14
 2   int rdmnum = rand() % MAXLEN +1;
15
16
 3  char rdmchar = 64 + (rand() % CHAR +1);
17
18
19
 4   char *puffer;
20
 5   puffer = (char*) malloc (MAXLEN+2); 
21
22
 6   char* strncat(puffer, rdmchar, rdmnum);
23
24
 7   printf("%s\0", puffer);
25
26
27
28
29
 8  return 0;
30
}



Die Ausgabe sind lediglich immer nur 3 Zeichen davon sind die ersten 2 
statisch also verändern sich nicht bei einem neustart lediglich das 
letzte ist zufällig: ϸ↕

Ich selber kann mir nicht erklären warum der code nicht dass macht was 
ich eigentlich erwartet hätte ich denke allerdings der fehler liegt 
zwischen zeile 4 - 6.

Kann mir jemand helfen und mir meinen Fehler aufzeigen?

MfG

Ps: Bekomme mit angehängter datei einen internal server error wenn ich 
zur vorschau will

von ... (Gast)


Lesenswert?

klitzekleine Hilfe ;)

mach mal einen neuen char* und kopiere da deinen rdmchar rein, weil:
char* strncat(char* destination, char* source, size_t num);

von Arc N. (arc)


Lesenswert?

Ein paar Anmerkungen...
Was liefert malloc zurück und wie müssen Zeichenketten in C aufgebaut 
sein damit Funktionen wie strncat richtig arbeiten können?
strncat s.o. zudem sollte der Compiler an der Stelle (6) mindestens eine 
Warnung ausgegeben haben (eigentlich einen Fehler und das Programm nicht 
übersetzen).

von M. T. (yohojoe)


Lesenswert?

Arc Net schrieb:
> Ein paar Anmerkungen...
> Was liefert malloc zurück und wie müssen Zeichenketten in C aufgebaut
> sein damit Funktionen wie strncat richtig arbeiten können?
> strncat s.o. zudem sollte der Compiler an der Stelle (6) mindestens eine
> Warnung ausgegeben haben (eigentlich einen Fehler und das Programm nicht
> übersetzen).


malloc ist doch eigentlich ein void liefert also gar nichts zurück, ich 
habe hier aber einen char deswegen muss ich doch zusätzlich einen 
(char*) mit hinschreiben.

ich glaube ich sehe einen fehler:

zeile 3 generiert nur einen buchstaben, daraus folgt dass strncat gar 
nicht mehrere zeichen verketten kann da nur eines generiert wird.
Als lösung müsste man folglich dafür sorgen dass zeile 3 öfters 
ausgeführt wird und zwar mind. so oft wie MAXLEN?


Warnungen/errors werden keine angezeigt :/ (CodeBlocks ver. 10.05)

von Uwe (Gast)


Lesenswert?

Funktionen auf strings benötigen zwingend eine 0x00 Byte als 
terminierung
 ( Also solche Funktionen wie strncat).

von Karl H. (kbuchegg)


Lesenswert?

M. T. schrieb:
> Arc Net schrieb:
>> Ein paar Anmerkungen...
>> Was liefert malloc zurück und wie müssen Zeichenketten in C aufgebaut
>> sein damit Funktionen wie strncat richtig arbeiten können?
>> strncat s.o. zudem sollte der Compiler an der Stelle (6) mindestens eine
>> Warnung ausgegeben haben (eigentlich einen Fehler und das Programm nicht
>> übersetzen).
>
>
> malloc ist doch eigentlich ein void liefert also gar nichts zurück,

nicht ganz.

malloc liefert einen void*. Und das ist ein Unterschied. Denn malloc 
liefert damit eine Adresse zurück und das void sagt lediglich aus, dass 
nicht weiter klar ist, worauf (also auf welchen Datentyp) diese Adresse 
eigentlich zeigt. Das macht aber nichts, denn du weist diese Adresse der 
Pointer Variablen zu und damit ist dann klar, dass dieser Pointer (weil 
er ein char* ist) auf Character zeigt.

> ich
> habe hier aber einen char deswegen muss ich doch zusätzlich einen
> (char*) mit hinschreiben.

Wenn du den schreiben musst, dann programmierst du nicht C sondern C++. 
In C machst du den Cast lieber wieder raus.
Denn: du brauchst ihn nicht
      er kann dir aber einen fiesen Fehler verstecken


> ich glaube ich sehe einen fehler:

ich seh noch einen Fehler.
Du brauchst überhaupt kein strncat.

  einfach den Speicher allokieren
  danach fasst du diesen Speicher wie ein Array auf (ein Array aus
  char) und weist jeder Array-Position einen zufälligen Buchstaben zu


Du verkomplizierst momentan die Aufgabe grundlos.

von Karl H. (kbuchegg)


Lesenswert?

> Dafür brauche ich den memory allocation befehl (malloc) und ich
> muss wissen wie groß der reservierte speicher sein soll:
> (maximale länge der zeichenkette + 2 zeichen für die terminierung
> die meines wissen so aussieht: \0)

* warum + 2?
  wenn du einen Text "Hallo" hast, dann hat der 5 Zeichen. Das Array
  muss 6 Zeichen groß sein, weil ja noch das abschliessende \0 da
  mit rein muss.
  Um also einen Text mit n Buchstaben zu speichern, brauchst du ein
  Array der Größe n+1

> (maximale länge der zeichenkette + 2 zeichen für die terminierung

* genau das steht aber nicht in der Aufgabe! In der Aufgabe steht, du 
sollst dir eine zufällige Textlänge bestimmen und den Speicher genau so 
groß anlegen, dass ein derartiger Text da reinpasst. Die zufällige 
Textlänge hast du ja bereits bestimmt:

  int rdmnum = rand() % MAXLEN +1;

in rdmnum hast du eine zufällige Textlänge, die zwischen 1 und MAXLEN 
liegt.
Und genau dafür sollst du Speicher allokieren. Wenn dein Text also aus 
rdmnum Zeichen bestehen soll, wieviel Speicher musst du dann allokieren? 
Na, ja wohl rmdnum+1 chars. Also

  puffer = malloc( rmdnum + 1 );

jetzt zeigt puffer auf einen Speicher, der gross genug ist, um darin 
rmdnum darstellbare Zeichen PLUS das obligatorische \0 Zeichen als 
Abschluss des Strings zu speichern.

Du musst jetzt nur noch entsprechend rmdnum darstellbare Zeichen da 
reinklamüsern und das \0 an die letzte Stelle in diesem 'Array' bringen

   for( i = 0; i < rmdnum; i++ )
     puffer[i] = .............. zufälliges Zeichen bestimmen

   puffer[rmdnum] = '\0';

und fertig. Zumindest dieser Teil der Aufgabenstellung.

von Stefan P. (form)


Lesenswert?

M. T. schrieb:
> (maximale länge der
> zeichenkette + 2 zeichen für die terminierung die meines wissen so
> aussieht: \0)

Das ist übrigens nur 1 Zeichen.

von Andreas D. (rackandboneman)


Lesenswert?

Bevor Missverständnisse entstehen:

"gestellten aufgabe in informatik (c#)"

Der hier diskutierte Code ist aber C, kein C#. Und wird in einer C# 
Umgebung auch nur im Ansatz als unmanaged Code und mit zusätzlicher 
Nutzung eines Präprozessors laufen.

von Karl H. (kbuchegg)


Lesenswert?

> char rdmchar = 64 + (rand() % CHAR +1);
>
> dieser gibt mir also die buchstaben A-Z zufällig aus

Wie das?

Ich weiß zwar nicht, wie du CHAR definiert hast, aber ich würde so 
vorgehen:
Annahme: wir reden vom ASCII Code.

Seh ich mir die Codetabelle des ASCII Codes an, zb die hier

http://www.torsten-horn.de/techdocs/ascii.htm

dann fällt mir auf, dass die ganzen Großbuchstaben alle hintereinander 
kommen. D.h. ich brauch nur Zufallszahlen erzeugen, die genau diese 
Codes abdecken, und die wie einen char behandeln.

Es gibt 26 Großbuchstaben. Also brauch ich erst mal eine Zufallszahl 
zwischen 0 und 26 (exklusive)

    rand() % 26

macht das. Damit hab ich irgendeine Zahl im Bereich 0 ... 25

Zähle ich da noch den ASCII Code von 'A' dazu, dann kriege ich eine 
somit zufällige Zahl, die genau einem der ASCII Codes der Zeichen 'A' 
bis 'Z' entspricht.

Also:

  char rdmchar = 'A' + rand() % 26;

die 26 könnte man noch etwas schöner formulieren. Das ist ja nichts 
anderes als die Differenz der Codes von 'Z' und 'A'. Denn das müssen 
wieder die 26 sein

  char rdmchar = 'A' + rand() % ( 'Z' - 'A' + 1 );

Und fertig. In rmdchar steht der ASCII Code, und zwar irgendeiner, der 
eines der Zeichen aus dem Bereich 'A' bis 'Z' repräsentiert. Gebe ich 
das als char auf den Monitor aus, dann wird die genau diesen Buchstaben 
hinpinseln.

von Borislav B. (boris_b)


Lesenswert?

M. T. schrieb:
> vor einer mir gestellten aufgabe in
> informatik (c#)

M. T. schrieb:
> char *puffer;
>     puffer = (char*) malloc (MAXLEN+2);

Wenn das C# ist, fress ich nen Besen...

von Karl H. (kbuchegg)


Lesenswert?

Andy D. schrieb:
> Bevor Missverständnisse entstehen:
>
> "gestellten aufgabe in informatik (c#)"
>
> Der hier diskutierte Code ist aber C, kein C#.

Ja, das ist mir auch schon aufgefallen.

In der Aufgabenstellung steht aber eindeutig C.

Und wenn ich hinzufügen darf, finde ich es bezeichnend, wenn ein Schüler 
nicht mal den Namen der Programmiersprache kennt, in der er 
programmieren soll.

von Nilix (Gast)


Lesenswert?

Also ich denke die Lösung sieht so aus wenn ich mich nicht verlesen habe 
oder in der Eile vertippt.
Nicht kompilliert und geprüft und sicher verbesserungsfähig.
Aber einfach mal ein Ansatz evtl. hilfts.


#define MAXLEN 20

//====================================================================== 
============================
// Aufrufende funktion muss Speicer bereinigen mit free(char*);
//====================================================================== 
============================
char* func()
{
int i,lenght;
char *ptr,c;


//ermittle zufällige Zeichenlänge
randomize();
while(1)
 {
 lenght=rand();
 if(lenght > 0 && lenght < MAXLEN) break;
 }

//Speicher allokierung
ptr=malloc(lenght+2);
if(ptr == NULL) return(NULL);

//Speicer füllen
for(i=0;i<lenght;i++)
 {
 while(1)
   {
   c=(char) rand();
   if(c > 0x40 && c < 0x5B) break;//A-Z
   }

 ptr[i]=c;
 ptr[i+1]=0x00;
 }


return(ptr);
}

von thomas d. (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und wenn ich hinzufügen darf, finde ich es bezeichnend, wenn ein Schüler
> nicht mal den Namen der Programmiersprache kennt, in der er
> programmieren soll.

da fehlen mehr als nur die basics ...

von Karl H. (kbuchegg)


Lesenswert?

Nilix schrieb:
> Also ich denke die Lösung sieht so aus wenn ich mich nicht verlesen habe
> oder in der Eile vertippt.
> Nicht kompilliert und geprüft und sicher verbesserungsfähig.

:-)
Den Aufruf von randomize() solltest du besser weglassen (wenn randomize 
das macht, was ich denke das es macht). Lass den Zufallszahlengenerator 
arbeiten! Du hilfst ihm nicht dabei gute Zufallszahlen zu erzeugen, wenn 
du bei jedem Aufruf der Funktion ihm ins Handwerk pfuschst. Den srand 
bzw bei dir eben den randomize macht man nur ein einziges mal pro 
Programmlauf! Alles andere ist kontraproduktiv.

Schön finde ich, dass du das Problem der Nicht-Gleichverteilung durch 
die Bereichseinschränkung mittels Modul berücksichtigt und umgangen 
hast. Auch wenn ich nicht glaube, dass sein Lehrer darauf wert legt und 
du durch den Zwangs-randomize diese Bemühung wieder zunichte machst. 
Allerdings ist die Version mit Endlosschleife + Rausbreaken jetzt nicht 
wirklich 'schön'. Aber Schönheit liegt im Auge des Betrachters :-) Nur 
gibt es in deinem Code eine eigentlich naheliegende Lösung dieses 
Schönheitsmakels.


> ptr=malloc(lenght+2);

warum +2 ?

> if(ptr == NULL) return(NULL);
>
> //Speicer füllen
> for(i=0;i<lenght;i++)
>  {
>  while(1)
>    {
>    c=(char) rand();
>    if(c > 0x40 && c < 0x5B) break;//A-Z

Der Compiler kennt schon die ASCII-Codes. Die brauchst du nicht selber 
nachschlagen :-)

     if(c >= 'A' && c <= 'Z') break;

dann brauchst du auch den Kommentar nicht und das ist immer ein gutes 
Zeichen. Eine Codeänderung, die einen Kommentar überflüssig macht, ist 
immer eine gute Änderung.

>    }
>
>  ptr[i]=c;
>  ptr[i+1]=0x00;

Ist eine Fleissaufgabe. Einmal nach beenden der for-Schleife hätte es 
auch getan. Aber: So hat man für den Debugger immer einen schönen String 
im Array.

von Nilix (Gast)


Lesenswert?

Hallo Karl Heinz
Du hast recht, ich habe nur mal kurz in 2 Minuten eine lösung gezaubert.
Ich sagte ja Verbesserungswürdig nur als Ansatz gedacht nicht als 
endgültige Lösung.
Danke dennoch für den Hinweiß

von Rolf M. (rmagnus)


Lesenswert?

Karl Heinz Buchegger schrieb:
> if(c >= 'A' && c <= 'Z') break;

Oder gleich ganz unabhängig von der Zeichenkodierung:

if (isalpha(c) && isupper(c)) break;

von Andreas D. (rackandboneman)


Lesenswert?

"da fehlen mehr als nur die basics ..."

Evtl auch beim Aufgabensteller ... Evtl wurde gedacht da C++ bis auf 
Ausnahmen eine Übermenge von C ist C# es auch (@yohojoe es ist NICHT so, 
C# hat mehr mit Java als mit C++ gemein!) ...

von M. T. (yohojoe)


Lesenswert?

1. Ich bin Student kein Schüler

2. Danke, ich hab jetzt zum ersten mal gehört dass C# nicht gleich C 
ist, ich habe es eher für eine andere "schreibweise" von C gehalten.

3. Ja es fehlen womöglich noch ziemlich viele Basics, liegt aber daran 
dass ich E-technik studiere und nicht informatik. Informatik habe ich 
nur eine Vorlesung pro Woche (meiner Meinung nach viel zu wenig), 
weswegen man sich das meiste selber beibringen muss wofür aber sehr oft 
nur wenig zeit bleibt.
Dh. natürlich auch dass ich manche Aufgaben nur mit mir bekanntem 
Werkzeug lösen kann obwohl eine andere Lösung vllt viel einfacher wäre

von M. T. (yohojoe)


Lesenswert?

So ich bin jetzt weitergekommen hab die puffer funktion und deren 
beschreibung in ein array. Dazu kommt noch eine Vertauschung von element 
0 und dem letzten element des arrays und die ausgabe des arrays mit 
vertauschung zum vergleich mit dem original. Problem: das programm 
stürzt ab und ich weiß nicht wieso. Kann es evtl. an den warnungen 
liegen die ich weiter unten beschrieben hab? und wie bekomme ich diese 
weg?

leider war vieles davon trial & error bis ich irgendwann noch darauf 
gekommen bin. Va. die pointer bereiten mir noch ziemlich viele Probleme 
:(.

grüße





1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <time.h>
4
#include <string.h>
5
#define MAXLEN 5
6
#define CHAR 26
7
#define ARRAYLENGTH 10
8
9
char* zufall (char* buf)
10
{
11
12
13
14
    /**** VARIABLEN ****/
15
16
    int zufallszahl;
17
    int i;
18
19
20
21
    /**** GENERIERUNG DER ZUFALLSZAHL ****/
22
23
    zufallszahl = rand() % MAXLEN +1;
24
25
26
    /**** DYNAMISCHE SPEICHERVERWALTUNG ****/
27
28
    buf = (char*) malloc (zufallszahl+1);
29
30
31
    /**** BESCHREIBUNG DES PUFFERS ****/
32
33
    for(i=0; i<zufallszahl; i++)
34
    {
35
       buf[i] = 64 + (rand() % CHAR +1);
36
    }
37
38
39
    /**** RUECKGABE MIT NULLTERMINIERUNG ****/
40
41
    buf[i] = '\0';
42
    return buf;
43
44
45
46
    }
47
48
49
50
51
52
int main()
53
{
54
        srand(time(NULL));
55
56
        char buf;
57
        int i;
58
        char* array [ARRAYLENGTH];
59
        char* hilfs;
60
61
        for(i=0; i<ARRAYLENGTH; i++)
62
        {
63
            array[i] = zufall(buf);
64
            printf("%d: %s\n", i+1, array[i]);
65
        }
66
67
68
69
70
        for(i=0; i<ARRAYLENGTH; i++)
71
        {
72
            array[i] = zufall(buf);
73
            hilfs = array[0];
74
            array[0] = array[ARRAYLENGTH];
75
            array[ARRAYLENGTH] = hilfs;
76
            printf("Nach Vertauschung\n\n\n\n");
77
            printf("%d: %s\n", i+1, array[i]);
78
79
        }
80
81
82
83
    return 0;
84
}

warning: passing arg 1 of `zufall' makes pointer from integer without a 
cast
warning: passing arg 1 of `zufall' makes pointer from integer without a 
cast

in den zeilen:
1
array[i] = zufall(buf);

von Arc N. (arc)


Lesenswert?

> Kann es evtl. an den warnungen liegen die ich weiter unten beschrieben
> hab?

Ja

> und wie bekomme ich diese weg?

- Was liefert die Funktion zufall zurück und wo wird das gespeichert?
- Als was wird buf in der Funktion zufall verwendet (warum soll buf dann 
nochmal übergeben werden bzw., um etwas Verwirrung zu stiften, warum 
wäre void zufall(char** buf) { ... } richtiger (aber nicht unbedingt 
sinnvoll))

von M. T. (yohojoe)


Lesenswert?

> um etwas Verwirrung zu stiften

:D das ist gelungen.

Also die funktion liefert verschiedene chars welche in einem array 
gespeichert sind.

buf wird verwendet als ein array der diesen string speichert?


1
 for(i=0; i<ARRAYLENGTH; i++)
2
        {
3
            array[i] = zufall(buf);
4
            printf("%d: %s\n", i+1, array[i]);
5
        }

Also für mich hört sich das richtig an.

Der fehler liegt meiner meinung nach bei den typbezeichnungen und den 
pointern

von M. T. (yohojoe)


Lesenswert?

Ich verstehe vor allem den unterschied nicht:


char *buchstabe: pointer buchstabe mit typ char?

char* buchstabe: char pointer der auf die variable buchstabe zeigt??


wofür genau man das brauchen kann ist mir nicht bekannt :(

kann es vielleicht sein dass man beim 2. fall, zb auch einen int* auf 
die variable zeigen lassen kann und so mehrere typen vor der variablen 
haben kann?

von der mechatroniker (Gast)


Lesenswert?

Ganz einfach: der C-Compiler ignoriert Leerzeichen (meistens; 
wesentliche Ausnahme ist da, wo ohne Leerzeichen zwei Bezeichner zu 
einem verschmelzen würden).

Beide Schreibweisen sind daher gleichwertig und definieren eine Variable 
"buchstabe", die vom Typ "Zeiger auf char" ist.

von Xilef (Gast)


Lesenswert?

Um mal ein bisschen vom Thema abzuschweifen:

Wieso kann man hier malloc eine feste Größe übergeben, ohne 
sizeof(char)? So wie im Post von kbuchegg:
1
malloc( rmdnum + 1 );

Ist ein char immer ein byte? Ist folgendes richtiger, oder nur 
überflüssig?
1
malloc( sizeof(char) * (rmdnum + 1) );

von der mechatroniker (Gast)


Lesenswert?

Die zweite Schreibweise ist daher an und für sich logischer: char* wäre 
als eine Einheit zu sehen (nämlich der Typ) und buchstabe als die andere 
(nämlich der Name der definierten Variable).

Warum man normalerweise die erste Schreibweise verwendet hängt mit einer 
Unschönheit zusammen, die die Erfinder von C in die Sprache 
hineindesignt haben.

Preisfrage:

Definiert
1
char* a, b

wirklich zwei Variablen vom Typ "Zeiger auf char"?

Wenn du die Antwort herausgefunden hast, merkst du, was ich mit 
Unschönheit meinte.

von der mechatroniker (Gast)


Lesenswert?

> Wieso kann man hier malloc eine feste Größe übergeben, ohne
> sizeof(char)? So wie im Post von kbuchegg:

Weil sizeof(char) per Definition 1 ist. Sprich überall, wo eine Größe 
einer Datenmenge verwendet wird (Parameter von malloc, Ergebnis von 
sizeof) ist die Größe in Vielfachen der Größe eines char gemeint.

von M. T. (yohojoe)


Lesenswert?

> Preisfrage:

> Definiert
>
1
> char* a, b
2
>

> wirklich zwei Variablen vom Typ "Zeiger auf char"?


nein meines wissens nach nur eine variable vom typ zeiger auf char und 
zwar a.


aber schonmal danke wusste ich davor nicht :)

von Malte S. (maltest)


Lesenswert?

M. T. schrieb:
> array[0] = array[ARRAYLENGTH];
>             array[ARRAYLENGTH] = hilfs;

Abgesehen von den angewarnten Stellen und den Problemen mit char vs. 
char* ist array[ARRAYLENGTH] außerhalb von array, das nur ARRAYLENGTH 
Elemente hat. Ganz gefährlicher Fehler sowas.

von Karl H. (kbuchegg)


Lesenswert?

M. T. schrieb:
>> um etwas Verwirrung zu stiften
>
> :D das ist gelungen.
>
> Also die funktion liefert verschiedene chars welche in einem array
> gespeichert sind.


Deine Denkweise ist Quatsch.

Diese Funktion
1
char* zufall (char* buf)
2
{
3
  ...
4
}

liefert einen Pointer. Aus. Ende. Punkt.

Mehr steht da nicht da.

Da du die Funktion geschrieben hast, weißt du, dass dieser Pointer auf 
einen Speicherbereich zeigt, in dem ein Text gespeichert ist. Und das 
reicht dann schon. Die Funktion braucht auch kein Pointer Argument! Wozu 
soll das gut sein? Kein Mensch braucht dieses Argument innerhalb der 
Funktion.

1
...
2
int main()
3
{
4
  char* pText;
5
6
  pText = zufall();
7
8
  printf( "%s\n", pText );
9
10
  free( pText );
11
}

von Karl H. (kbuchegg)


Lesenswert?

Und zieh deinen Code nicht so in die Länge!
Das bringt dir nichts, wenn du 2 Millionen Leerzeilen einstreust. Alles 
was du damit tust, ist deinen Code unübersichtlicher zu machen, weil du 
ihn rein optisch nicht mehr überblicken kannst.

Deine Kommentare solltest du auch überdenken. Die sind nämlich sinnlos, 
weil sie mir nichts erzählen, was nicht auch im Quelltext steht. Wer bei
1
    /**** VARIABLEN ****/
2
3
    int zufallszahl;
4
    int i;

nicht innerhalb einer halben Sekunde sieht, dass hier Variablen 
definiert werden, der soll sich doch bitte sein Lehrgeld wiedergeben 
lassen, seine Lehrer haben dann nämlich ganz offensichtlich versagt. Ein 
derartiger Kommentar bewegt sich auf dem Niveau von einem Schild nebem 
einem roten Button zum Drücken, auf dem steht "Dies ist ein roter Knopf 
zum Drücken."
Völlig sinnlos.
Erzähl mir in deinen Kommentaren etwas, was ich nicht im Source Code 
sehe!
1
    /**** GENERIERUNG DER ZUFALLSZAHL ****/
2
3
    zufallszahl = rand() % MAXLEN +1;

das hier eine Zufallszahl generiert wird, sehe ich auch so. Dazu brauch 
ich keinen Kommentar. Aber was macht diese Zufallszahl? Was hat es damit 
für eine Bewandtnis? Wofür wird die verwendet? Warum +1? Wo kommt das 
MAXLEN her? Welche Bedeutung hat dieses?
All das sind beispielsweise Dinge, die mich interessieren würden. Aber: 
Du verrätst sie mir nicht. Dafür verrätst du mir, dass hier eine 
Zufallszahl generiert wird. Da kann ich nur sagen "Gähn - als ob ich das 
nicht durch die Verwendung der Funktion rand() nicht auch selbst gesehen 
hätte"

Sieh dir die Namen deiner Variablen bzw. der Funktionen an! Inwieweit 
erzählen mir die welche Funktion sie innerhalb des Programms erfüllen? 
Gar nicht. Eine Funktion namens 'zufall' erzählt mir nichts, was sie 
tut. Was macht sie denn wirklich? Na, sie erzeugt einen Zufallstext. 
Also wäre es nur folgerichtig, wenn sich dieses auch im Namen 
wiederspiegeln würde! Was macht denn deine Variable 'zufallszahl' 
innerhalb der Funktion? Welche Bedeutung hat die denn? In ihr ist 
gespeichert, wie lange der Text werden soll. Also wäre es nur 
vernünftig, dass sich dieses auch in ihrem Namen wiederspiegelt. In 
erster Linie ist diese Variable die Länge des zu erzeugenden Textes. 
Dass diese Länge durch eine Zufallszahl ermittelt wird, ist zwar nett, 
ist aber ein Detail, welches mich in weiterer Folge nicht wirklich 
interessiert. Irgendwo muss diese Länge herkommen. In diesem Fall ist es 
eben durch eine Zufallszahl. Aber ob das durch eine Zufallszahl gemacht 
wird, oder ob das zb durch eine Benutzereingabe gemacht wird, ändert 
nichts daran, dass sich bei dieser Zahl in erster Linie um die Länge des 
zu erzeugenden Textes handelt - das ist die wichtige Information und 
nicht wie diese Zahl zustande kommt.

1
char* rndText( void )
2
{
3
  int   textLength;
4
  int   i;
5
  char* pText = NULL;
6
7
  textLength = rand() % MAXLEN + 1;
8
  pText = malloc (textLength*sizeof(char) + 1);
9
10
  for(i=0; i<textLength; i++)
11
  {
12
    pText[i] = 'A' + (rand() % CHAR +1);
13
  }
14
  pText[i] = '\0';
15
16
  return pText;
17
}

Sieh dir diese Funktion durch. Zum Beispiel die Zeile
1
  textLength = rand() % MAXLEN + 1;
Braucht es da noch irgendwelche Kommentare? Nicht wirklich. Im 
Programmtext selber steht, was da passiert. Da wird die Länge des Textes 
'erzeugt'. Das kann ich unmittelbar daran ablesen, dass eine Variable 
namens textLength einen Wert bekommt. Ich kann auch ablesen, dass dieser 
Wert sich irgendwie aus einer Zufallszahl ermittelt. Das einzige was 
nicht ablesbar ist, ist was es mit dem MAXLEN auf sich hat.
AUch ist für die Funktion insgesammt nicht ablesbar, welche Regeln für 
die  'Buchstaben' innerhalb des Textes gelten (ob da zb nur 
Grossbuchstaben enthalten sein werden, oder auch Kleinbuchstaben. Ob man 
mit Ziffern rechnen muss und/oder Sonderzeichen und wenn ja mit 
welchen). Das sind die Dinge, die kommentiert werden müssen und nicht, 
dass da jetzt ein Return gemacht wird. Denn das seh ich auch im Code 
selber. Dazu brauch ich deine Kommentare nicht, damit ich das sehe. So 
blind bin ich nicht.

Im Kommentar steht das WARUM. Im Code steht das WIE.

von M. T. (yohojoe)


Lesenswert?

Malte S. schrieb:
> Abgesehen von den angewarnten Stellen und den Problemen mit char vs.
> char* ist array[ARRAYLENGTH] außerhalb von array, das nur ARRAYLENGTH
> Elemente hat. Ganz gefährlicher Fehler sowas.

EDIT: Hab grad herausgefunden was du meinst, in die klammer gehört 
[ARRAYLENGTH-1]. Da es zwar 10 werte hat, es aber von 0 - 9 geht ist 
ARRAYLENGTH mit 10 gar nicht vorhanden, deswegen auch der absturz. 
Ziemlich leichtsinniger Fehler von mir


Also die warnung sind weg, hatte in der main buf als variable deklariert 
obwohl es eig ein pointer sein sollte.

Das was du hier angibst sollte eigentlich eine vertauschung sein vom 
ersten mit dem letzten array element.

Allerdings ist es in der Aufgabenstellung so beschrieben, dass man die 
vertauschung in einer funktion erreichen soll, der die arrayeinträge als 
argumente übergeben werden. Mal sehn was ich daraus machen kann. Es ist 
nur ziemlich niederschlagend wenn jeder aufgabenteil an die 5 stunden 
braucht und hinterher ist er auch noch falsch....

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.