Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?
-
So ich melde mich nochmal erneut. Ich habe mich nochmal erneut daran versucht und habe das mit der nullten Stelle soweit kapiert. Im Internet hat man kaum etwas dazu gefunden, deshalb kam ich irgendwann auch so auf die Idee: Nur irgendwie denke ich, man hätte es noch sauberer lösen können und mehr die Zeigerarithmetik verwenden können. Hier der Code:
#include <stdlib.h> #include <string.h> #include <stdio.h> #define MAX 130 /*1 Byte für Zeichenkette = '\0' | 1 Byte extra, da wir ab i = 0 zählen*/ int main(){ int zahl = 0, i; char z[MAX]; /*Array MAX groß*/ printf("Gebe maximal 128 Zeichen in einer Zeile ein: "); fgets(z, MAX, stdin); /*ließt die ganze Zeile ein bis "MAX" Zeichen erreicht sind*/ for(i=0; *(z+i) != 0; i++) /*Zähle bis zum Ende der Zeichenkette*/ { putchar(*(z+i)); /*Kontrolle: Eingabe = Ausgabe*/ zahl++; } zahl = zahl - 1; /*Minderung wegen der Versetzung um ein Byte*/ printf("Anzahl:%d",zahl); /*Ausgabe Anzahl*/ return 0; }
-
Probierst du deine Programme nicht aus?
PS:
1 Byte extra, da wir ab i = 0 zählen
Ein Array
int i[2];
hat zwei Elemente.i[0]
undi[1]
.
-
@SeppJ sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Probierst du deine Programme nicht aus?
Natürlich probiere ich meine Programme aus. Funktioniert doch. Das ein Array bei 0 anfängt weiß ich
-
@Ravensouth
Teste dein Progamm mal mit nem Textfile als Input wo z.B. "test" (ohne folgenden Zeilenumbruch) drinsteht.
Output:Gebe maximal 128 Zeichen in einer Zeile ein: testAnzahl:3
-
fgets
speichert auch das Newline-Zeichen\n
(im Gegensatz zugets
oderscanf("%s")
- darum das Dekrementieren.Ein Möglichkeit ist mittels dem PP den Format-String für
scanf
zusammenzusetzen:#define STR(X) STRINGIFY(X) #define STRINGIFY(X) #X
und dann
scanf("%" STR(MAX) "s", z);
s.a. Specifying the maximum string length to scanf dynamically in C (like "%*s" in printf)
sowie der abgeänderte Ideone-Code.
-
@Ravensouth sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Das ein Array bei 0 anfängt weiß ich
Ja, aber ich habe den Eindruck, du ziehst die falschen Schlüsse.
-
@Th69
Man kann schonfgets
verwenden. Man muss bloss nachher das abschliessenden\n
wegmachen wenn man es nicht haben will.
-
Ok das fgets mit /n abschließt wusste ich nicht. Danke für diese Information.
-
@SeppJ sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
@Ravensouth sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Das ein Array bei 0 anfängt weiß ich
Ja, aber ich habe den Eindruck, du ziehst die falschen Schlüsse.
Wenn ich
int i[2]
als Array habe, dann müssten dochi[0]
,i[1]
undi[2]
enthalten sein?
-
@Ravensouth
Nein!
int i[2];
hat 2 Elemente ... wie SeppJ oben schon erwähnt hat ...
-
@Ravensouth sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Ok das fgets mit /n abschließt wusste ich nicht. Danke für diese Information.
es ist \n
Das ist eine Escapesequenz und steht für ein Zeichen@Ravensouth sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Wenn ich
int i[2]
als Array habe, dann müssten dochi[0]
,i[1]
undi[2]
enthalten sein?Nein.
Bei der Definition werden die Anzahl der Elemente angegeben.
In diesem Fall 2. Und wenn man bei 0 anfängt kommt man nur bis 1 als Index.
-
@Ravensouth sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Im Internet hat man kaum etwas dazu gefunden,
Ach echt? Schau dir nochmal mein Beispiel an, was ich gepostet habe. Ich zitiers dir sogar nochmal:
@Luks-Nuke sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Das ist übrigens mMn die Musterlösung und benutzt Zeigerarithmetik.
Btw statt
*z(i + 1)
kannst du auch ganz einfachz[i + 1]
schreiben. Damit schälst du die gleiche Birne.Wenn bei meinem gepostetem Vorschlag noch Sachen sind, die du nicht kapierst kannst du gerne hier nachfragen, was genau du nicht verstehst.
-
@hustbaer sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Wenn man mit Zeigern arbeitet und mit
++
zum nächsten Element kommt, dann funktioniertEnde-Anfang
.Das setzt voraus, dass es sich um eine Plattform mit linearen Arbeitsspeicher handelt. Das ist mittlerweile Standard, war aber eben nicht immer der Fall. An mir persönlich ist der Kelch 8088/8086/80286 vorbei gegangen, da muss man neben dem Zeiger auch das Indexregister berücksichtigen. Nimmt man da nur den Zeiger können dort negative Werte herauskommen, wenn man das Indexregister dazu nimmt stimmt wieder alles.
-
@john-0 sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
@hustbaer sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Wenn man mit Zeigern arbeitet und mit
++
zum nächsten Element kommt, dann funktioniertEnde-Anfang
.Das setzt voraus, dass es sich um eine Plattform mit linearen Arbeitsspeicher handelt. Das ist mittlerweile Standard, war aber eben nicht immer der Fall. An mir persönlich ist der Kelch 8088/8086/80286 vorbei gegangen, da muss man neben dem Zeiger auch das Indexregister berücksichtigen. Nimmt man da nur den Zeiger können dort negative Werte herauskommen, wenn man das Indexregister dazu nimmt stimmt wieder alles.
Das ist dem Sprachstandard aber egal. Das Ergebnis von ++ ist garantiert immer größer als der vorherige Wert, und
Ende-Anfang
funktioniert auch garantiert positiv. Wenn du mit ++ über irgendwelche Grenzen laufen würdest, dann hast du den klassischen Fall, dass du einen Pointer erzeugt hast, der hinter ein Array zeigt. Das ist aber sowieso undefiniertes Verhalten und macht dir die obigen Garantien kaputt.Die Legalität von "darf man einen Pointer erzeugen der hinter ein Array zeigt?" ist hier schon zig mal diskutiert worden, und der Fall von segmentiertem Speicher ist genau der Fall, wo es schief gehen könnte. Und vermutlich der Grund, warum der Standard sagt, dass es UB ist.
Jedenfalls kann aus diesem Grund das Array gar nicht über solch eine Grenze verlaufen. Der Pointer zu dem das Array zerfällt ist garantiert geeignet, um das gesamte Array zu adressieren, nicht mehr und nicht weniger.
-
@SeppJ sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Die Legalität von "darf man einen Pointer erzeugen der hinter ein Array zeigt?" ist hier schon zig mal diskutiert worden, und der Fall von segmentiertem Speicher ist genau der Fall, wo es schief gehen könnte. Und vermutlich der Grund, warum der Standard sagt, dass es UB ist.
Aber zeigt nicht
std::end(my_array)
hinter mein Array? Und darf ich nichtend(array) - begin(array)
rechnen für die Länge? Das ist UB?
Edit: oh verdammt, hier ist C ohne ++. Ist da irgendwo ein Unterschied, der das in C++ gültig macht? Denn ansonsten hätte ich glaube ich ein Problem.
-
@wob sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
@SeppJ sagte in Zeichenkette einlesen und mittels Zeigerarithmetik die Anzahl der Zeichen ausgeben?:
Die Legalität von "darf man einen Pointer erzeugen der hinter ein Array zeigt?" ist hier schon zig mal diskutiert worden, und der Fall von segmentiertem Speicher ist genau der Fall, wo es schief gehen könnte. Und vermutlich der Grund, warum der Standard sagt, dass es UB ist.
Aber zeigt nicht
std::end(my_array)
hinter mein Array? Und darf ich nichtend(array) - begin(array)
rechnen für die Länge? Das ist UB?
Edit: oh verdammt, hier ist C ohne ++. Ist da irgendwo ein Unterschied, der das in C++ gültig macht? Denn ansonsten hätte ich glaube ich ein Problem.Ich habe es jetzt nicht so exakt auf das letzte Byte gemeint. Eins hinter das Array ist noch ok.