Kämpfe jetzt schon seit 2 Tagen daran dieses Programm zum Laufen zu bringen, jedoch finde ich meinen Fehler nicht. Aufgabenstellung: Durch Eingabe des Strings "Wie gehts?" und einer Sperrung (leerzeichen zwischen den einzelnen Buchstaben) soll ein neuer String erzeugt werden solange es kleiner ist wie die maximale Byteeingabe in der main-funktion. Bsp: Sperrung: 3 "Wie gehts?" "W i e g e h t s ?" ############################################################ #include <stdio.h> #include <stdlib.h> #include <string.h> void aenderung(char *s[],int sperrung,int max){ int i,j=0,k; char hilfsv[max-1]; if(max>(((strlen(s)-1)*(sperrung+1))+1)){ for (i=0;i<strlen(s);i++){ hilfsv[j]=*s[i]; k=sperrung+1; while(k-1){ j++; hilfsv[j]=' ';}} strcpy(s,hilfsv); return s; } else printf("Fehler!\n"); } int main() { int sl=2; int max=60; char s[]="Wie gehts?"; aenderung(&s,sl,max); printf("%s",s); return 0; } #################################################### Kann mir einer erklären wo mein Fehler liegt?
Abgesehen davon, daß dein Quelltext gruselig zu lesen ist, sowie deine Fehlerbeschreibung keine ist, überschreibst du wahrscheinlich nicht nur s[] (das nur 11 Zeichen lang ist), sondern auch den Speicher dahinter?
Eben weil der Quelltext so grottig ist, sieht man auch kaum, daß du k nicht weiterzählst.
hilfsv[j]=*s[i]; soll wohl heißen: hilfsv[j]=s[i]; Entsprechend: char *s[] soll wohl heißen: char s[] oder char *s Hat das eigentlich mal ein Compiler so übersetzt? Wieso verheimlichst du dann die Fehlermeldungen?
Das mit dem k++; hab ich vergessen da hast du recht. Also mein Compiler hat es übersetzt und keine Fehlermeldungen gebracht. Jedoch hat er sich aufgehängt. Deshalb weiß ich die Fehler nicht...
Eine abschließende 0 sollte man an den String vielleicht auch anhängen. (Hast du in den zwei Tagen mal in ein C-Buch reingesehen?)
M. Bub schrieb: > Also mein Compiler hat es übersetzt und keine Fehlermeldungen gebracht. > Jedoch hat er sich aufgehängt. Dann hat er etwas übertrieben, sooo schlimm ist der Quelltext ja auch nicht, daß man sich aufhängen muß :-)
M. Bub schrieb: > Das mit dem k++; > hab ich vergessen da hast du recht. > > Also mein Compiler hat es übersetzt und keine Fehlermeldungen gebracht. Das kann ich mir ehrlich nicht vorstellen was passt zb hier nicht zusammen void aenderung(char *s[],int sperrung,int max){ **** .... return s; Mal ganz abgesehen davon, dass das so sowieso nicht geht. So kann man keinen String zurückgeben.
Ja danke für das ironische Kompliment ;-) Jetzt gibt er mir wenigstens was aus. H o ! ############################################################# #include <stdio.h> #include <stdlib.h> #include <string.h> void aenderung(char *s[],int sperrung,int max){ int i,j=0,k; char hilfsv[max-1]; if(max>(((strlen(s)-1)*(sperrung+1))+1)){ for (i=0;i<strlen(s);i++) { hilfsv[j]=s[i]; k=sperrung+1; while(k-1) { j++; hilfsv[j]=' '; k--; } } hilfsv[j+1]='\0'; strcpy(s,hilfsv); return s; } else printf("Fehler!\n"); } int main() { int sl=2; int max=60; char s[]="Hallo du!"; aenderung(&s,sl,max); printf("%s",s); return 0; }
Tipp Der Datentyp von s in void aenderung(char *s[],int sperrung,int max){ ist Blödsinn. Du hast kein Array von Pointern, du hast ein Array von Charactern. Und wenn du s dann später etwas mittels strcpy zuweisen willst, dann wäre es ganz gut, wenn s auch tatsächlich groß genug dafür ist (und genau dafür ist nämlich das max da, damit die Funktion das auch überprüfen kann) Dieses Array, welches du versuchst in die Funktion reinzugeben char s[]="Hallo du!"; aenderung(&s,sl,max); ist es ganz sicher nicht. Das ist nur 10 Zeichen gross. Da wirst du mit deinem gesperrtem Text nicht weit kommen. Und im übrigen ist es ganz gut, wenn man seine Funktionen nicht anlügt. Wenn das Argument nur Platz für 10 Zeichen bietet, dann ist es keine gute Idee, der Funktion weiszumachen, dass 60 Zeichen Platz hätten. Dein Aufruf soll so aussehen char s[40]="Hallo du!"; aenderung( s, sl, sizeof( s ) ); dann wid auch niemand angelogen und kein Array geht über.
Über Geschmack kann man streiten, über Stil sowieso. Trotzdem mal ein Vorschlag, den ich deutlich lesbarer finde:
1 | #include <stdio.h> |
2 | #include <stdlib.h> |
3 | #include <string.h> |
4 | |
5 | // kopiert String auf sich selbst, und fügt dabei je (nSperrung)
|
6 | // Leerzeichen ein:
|
7 | char *sperrungEinfuegen( char s[], int nSperrung, int max ) |
8 | {
|
9 | int iQuelle; |
10 | int iZiel = 0; |
11 | char hilfsv[max]; // geht so nur bei gcc, kein ANSI-C! |
12 | |
13 | if( max > (((strlen(s)-1)*(nSperrung+1))+1) ) |
14 | {
|
15 | for( iQuelle=0; iQuelle<strlen(s); iQuelle++ ) |
16 | {
|
17 | int iSperrung; |
18 | hilfsv[iZiel++] = s[iQuelle]; |
19 | for( iSperrung=0; iSperrung<nSperrung; ++iSperrung ) |
20 | {
|
21 | hilfsv[iZiel++] = ' '; |
22 | }
|
23 | }
|
24 | hilfsv[iZiel++] = '\0'; // terminieren |
25 | strcpy( s, hilfsv ); // zurückkopieren |
26 | return s; |
27 | }
|
28 | else
|
29 | {
|
30 | fprintf( stderr, "Fehler: String zu lang zum Sperren\n" ); |
31 | return NULL; |
32 | }
|
33 | }
|
34 | |
35 | int main() |
36 | {
|
37 | char s[200]="Wie gehts?"; |
38 | |
39 | sperrungEinfuegen( s, 2, sizeof(s) ); |
40 | printf( "%s\n", s ); |
41 | |
42 | return 0; |
43 | }
|
Darüber if(max>(((strlen(s)-1)*(sperrung+1))+1)){ muss ich noch brüten, aber ich denke das ist falsch.
Karl heinz Buchegger schrieb: > Darüber > > if(max>(((strlen(s)-1)*(sperrung+1))+1)){ > > muss ich noch brüten, aber ich denke das ist falsch. Sicher? Da sehe ich ausnahmsweise keine dunklen Wolken. Ich würde fast sagen, das war die einzige richtige Stelle im Programm :-)
Ich glaube das ist richtig ----- if(max>(((strlen(s)-1)*(sperrung+1))+1)){ ------ Das ist die Rechnung für die Bytes nach der Änderung. Die soll nämlich kleiner sein als die max. zugewiesen Anzahl
((strlen(s)-1)*(sperrung+1))+1 ist tatsächlich die Anzahl der Nutzbytes. Dazu kommt noch 1 für die abschließende 0, aber durch max>... klappt es gerade so. (Wenn ich mich jetzt nicht verzählt habe. Mal sehen, was KHB noch ausbrütet...)
Ja Klaus genauso hab ich es auch gerechnet. Mathematik ist eher meine Stärke als Programmieren aber da muss man halt durch...
Klaus Wachtler schrieb: > Sicher? Ich bin mir noch nicht sicher. Auf jeden Fall ist es mir deutlich zu kompliziert geschrieben. Was ist die Idee? Abzutesten ob der Platz ausreicht. Wieviel PLatz braucht man. zunächst mal den Platz für den Originalstring dann für jeden Zwischenraum noch einmal nSperrung Zeichen und natürlich +1 für das '\0' Zwischenräume gibt es Anzahl Zeichen - 1 Also wird benötigt len = strlen(s) len + ( len - 1 ) * nSperrung + 1 ich seh da jetzt nicht, wie man von dem auf ( len - 1 ) * ( nSperrung + 1 ) + 1 kommen könnte. Man zählt um 1 zu wenig. Auf der anderen Seite fragt er auf größer ab. Also: Könnte richtig sein. Für meinen Geschmack ist der Originalausdruck zu undurchsichtig und ich würde das wie gezeigt in die Einzelteile aufdröseln. Schön mit Zeilenumbruch und einem Kommentar daneben
1 | len = strlen(s) |
2 | |
3 | needed = len + // wir brauchen: Platz für den Originalstring |
4 | ( len - 1 ) * nSperrung + // für jeden Zwischenraum |
5 | 1; // und noch ein '\0' |
6 | |
7 | |
8 | if( max < needed ) { |
9 | printf( "Fehler" ); |
10 | return; |
11 | }
|
12 | |
13 | ...
|
dann ist das auch in 2 Monaten noch auf einen Blick nachvollziehbar.
Ja da sieht man deine Erfahrung... Hab leider nur nen Crashkurs trotzdem danke an euch dass es nicht noch mehr Nächte wurden ;)
Karl heinz Buchegger schrieb: > len + ( len - 1 ) * nSperrung + 1 > > ich seh da jetzt nicht, wie man von dem auf > > ( len - 1 ) * ( nSperrung + 1 ) + 1 Bei dir ist schon Platz für die abschließende 0 enthalten? Wenn ich nicht vertan habe, geht es so (statt len nehme ich mal x, ist kürzer):
1 | x + ( x - 1 ) * nSperrung + 1 + (x-1) - (x-1) |
2 | x + (x-1)*nSperrung + (x-1)*1 + 1 - (x-1) |
3 | x + (x-1)*(nSperrung+1) + 1 - (x-1) |
4 | (x-1)*(nSperrung+1) + x + 1 - (x-1) |
5 | (x-1)*(nSperrung+1) + 1 - (-1) |
6 | (x-1)*(nSperrung+1) + 2 |
Das ist um 1 größer als der Term aus dem Quelltext.
Karl heinz Buchegger schrieb: > Für meinen Geschmack ist der Originalausdruck zu undurchsichtig und ich > würde das wie gezeigt in die Einzelteile aufdröseln. Das ist natürlich richtig, das sehe ich auch so.
Klaus Wachtler schrieb: > Karl heinz Buchegger schrieb: >> len + ( len - 1 ) * nSperrung + 1 >> >> ich seh da jetzt nicht, wie man von dem auf >> >> ( len - 1 ) * ( nSperrung + 1 ) + 1 > > Bei dir ist schon Platz für die abschließende 0 enthalten? > > Wenn ich nicht vertan habe, geht es so (statt len nehme ich > mal x, ist kürzer): >
1 | > x + ( x - 1 ) * nSperrung + 1 + (x-1) - (x-1) |
2 | > x + (x-1)*nSperrung + (x-1)*1 + 1 - (x-1) |
3 | > x + (x-1)*(nSperrung+1) + 1 - (x-1) |
4 | > (x-1)*(nSperrung+1) + x + 1 - (x-1) |
5 | > (x-1)*(nSperrung+1) + 1 - (-1) |
6 | > (x-1)*(nSperrung+1) + 2 |
7 | > |
> > Das ist um 1 größer als der Term aus dem Quelltext. Eben. Und da er auf größer abfrägt, passt es wieder. Also Entwarnung, da hat mein Gefühl getrogen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.