C Char Array zuweisung und Ausgabe auf 10 Zeichen

ali7566

Lieutenant
Registriert
Feb. 2007
Beiträge
960
Hallo,

ich bearbeite gerade eine Übung die ich jetzt soweit von der Funktionaltät fertig programmiert habe, jedoch noch einen kleinen kosmetischen Fehler habe der nicht erwünscht ist.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>


int main(void)
{
char eingabe[100];
char eingabe2[10], eingabe3[90];
int i, zaehlen=0,buchstab=0, ziff=0;

do
{

printf("\nGeben Sie eine Zeichenkette ein: \n");
scanf("%s", eingabe);



for(i=0; i< 10; i++)
eingabe2= eingabe;

for(i=10;i<90;i++)
eingabe3[i-10]= eingabe;


for(i= 0;i < eingabe; i++)
{
zaehlen++;
if( eingabe >= 'A' && eingabe<= 'Z')
buchstab++;
if( eingabe>= '0' && eingabe<= '9')
ziff++;
}



printf("Der gespeicherte String ist: %s\n", eingabe2);

if(zaehlen > 11)
printf("Folgende Zeichen wurden abgeschnitten: %s\n", eingabe3);
else if( zaehlen < 11)
printf("Es mussten keine Zeichen abgeschnitten werden\n");


printf("Die Zeichenlaenge des String ist %d Zeichen lang\n", zaehlen);
printf("Es wurden %d Grossbuchstaben und %d Ziffern eingegeben \n",buchstab,ziff);




}while(eingabe[0]!= '@');


}



Ich lese eine Zeichenkette ein und möchte das 10 eigegebene Zeichen auf das Array eingabe2[] gespeichert werden und der rest in eingabe3[]. Soweit ja kein problem, jedoch habe ich dann bei der Ausgabe ein problem wenn ich über die 10 Zeichen gehe, dann nämlich werden mir die 10 Zeichen angezeigt jedoch dahinter mit einigen symbolen und nochmal mit der kompletten eingabe. Ich habe dem Array doch nur 10 variablen zur verfügung gestellt warum schreibt er da einfach munter weiter.

Ja ich weiß ich könnte auch bei printf() als formatierung .10 eingeben um es auf 10 zeichen zu beschränken, dies ist aber nicht erlaubt.

Habt ihr eine Idee ?

Gruß Ali.
 
Schaue mir den Text gerade an, aber erster gedanke: NULL-Terminierung ( '\0' ), das sagt aus das nichts mehr kommt...

also bsp. "10Zeichen\0" heißt das hinter dem "Zeichen" \0 nichts mehr kommt.
Weil er sonst bis zur nächsten Nullterminierung weiterschreiben würde und das somit solange macht, bis er eine im Speicher findet.
 
Das passiert weil scanf unsicher ist. Wenn der Eingabespeicher überschritten wird wird a) kein \0-Byte rangehangen (was das Ende des Strings andeutet) und b) der Speicher direkt dahinter wird überschrieben.

Nimm lieber fgets() mit stdin als FILE pointer, da kann man die Länge der Eingabe effektiv beschränken.
 
Ihr meint damit wohl das ich dem Array 11 variablen geben soll und damit das 11te Zeichen als Endezeichen verwendet werden kann ?
 
Ich darf nur scanf(_s) oder gets nehmen

@n1bbler: nein sie soll so oft hochzählen bis das ende des Arrays erreicht ist.
 
Genau. Strings sind in C(++) immer null-terminated, d.h. dass bei jedem String immer ein '\0' (oder als int einfach eine 0 zuweisen) am Ende steht. Das heißt wiederum, dass die Stringlänge immer um eins größer sein muss, als der String lang sein soll.
Code:
const unsigned int AnzahlZeichen = 10;

char eingabe2[AnzahlZeichen + 1], eingabe3[90]; // + 1 da \0 am Ende

// ...

for(i=0; i< 10; i++)
  eingabe2[i]= eingabe[i];
eingabe2[AnzahlZeichen] = 0; // teilt das Ende mit
 
Dann sag deinem Lehrer das er ein Idiot ist, weil er unsichere Programmierung lehrt. gets() ist genauso unsicher.
 
ali7566 schrieb:
Ihr meint damit wohl das ich dem Array 11 variablen geben soll und damit das 11te Zeichen als Endezeichen verwendet werden kann ?

Genau. :) Hast Du ein Characterarray mit z.B. 100 Nutzzeichen (also 100 Zeichen Text), dann sollte das gesamte Array eigentlich die Länge 101 haben, weil du ja immer noch einen Platz extra für die abschließende '\0' brauchst.

Das ist GANZ wichtig, wird häufig vergessen und ist auch einer der häufigsten Gründe für Speicherkorrumption in C-Programmen (und auch in C++-Programmen, die mit char-Arrays hantieren), denn viele Funktionen aus der C-Standardbibliothek verlassen sich darauf, irgend wo in dem übergebenen Array eine Null vozufinden, die sagt, wo schluss ist. Ist diese Null nicht vorhanden, wird fröhlich weiter gelesen / geschrieben - womöglich weit über das Ende des Arrays hinaus.
 
ok hab das Problem lösen können. Vielen dank.

@kugel: Ich glaube wenn ich das dem Prof sage geht das auf eine Schlägerei aus :D
Ergänzung ()

Was ich aber ganz komisch finde ist das wenn ich 10 Variablen beibehalte und nach der Schleife einfach hingehe und sage: eingabe2[10]= '\0' dann funktioniert das ganze auch.
 
ja das funktioniert, weil eingabe[10] das 11. element des arrays ist und nicht das zehnte, weil du bei 0 anfängst die elemente im array zu zählen. du hast dein array also erweitert.
 
Shagg schrieb:
ja das funktioniert, weil eingabe[10] das 11. element des arrays ist und nicht das zehnte, weil du bei 0 anfängst die elemente im array zu zählen. du hast dein array also erweitert.


So, wie ich seinen letzten Beitrag verstanden habe, hat er sein Array eben NICHT erweitert, setzt aber trotzdem das Element an der 11. Position (also mit Index 10) auf '\0'. Wenn dem so ist, dann ist das, was man so nett als 'undefiniertes Verhalten' bezeichnet. :king:

In einem Array auf ein Element zu langen, das hinter dem Ende des Arrays liegt, ist falsch und führt zu undefiniertem Verhalten. 'Undefiniertes Verhalten' heißt:

- kann rein zufällig immer gutgehen
- kann 20 mal klappen und beim 21. Mal deinen Computer in einen rauchenden Schrotthaufen verwandeln (klar, übertrieben ... aber der Standard würde dieses Verhalten durchaus erlauben :D)
 
Kenne mich in c nicht so gut aus, aber dachte, das man das array so einfacherweitern konnte. wie gesagt das kann auch falsch sein. sollte er sonst auf ein element außerhalb des arrays oder irgendeine andere nicht initialisierte variable zugreifen, ist es wie du gesagt hast natürlich total offen, wass passiert. kommt halt darauf an, was an der stelle im speicher steht.

das ist halt das problem mit c, da sehr hardware nah ist, hast du quasi freien zugriff auf den speicher. würde man sowas bei java machen, würde man sofort out of bounds bekommen. deshalb fände ich es besser, mit einer etwas sichereren sprache anzufangen.
 
kugel. schrieb:
Das passiert weil scanf unsicher ist. Wenn der Eingabespeicher überschritten wird wird a) kein \0-Byte rangehangen (was das Ende des Strings andeutet) und b) der Speicher direkt dahinter wird überschrieben.
Code:
char buffer[11];
int rc = scanf("%10s", buffer)
?

Frage im Kontext des Threads ist natürlich, ob VS6 das kann. Das Teil wurde vor der Standardisierung des C++-Standards fertiggestellt. Man muss stellenweise unkonformes C++ schreiben, nur damit das blöde Teil das frisst. Kann VS6 nix für an sich, sollte man aber eben deshalb auf keinen Fall mehr verwenden. Bestätigt mal wieder meine Meinung über Programmierung an Unis.
 
Zuletzt bearbeitet:

Ähnliche Themen

Zurück
Oben