PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ein kleines variablen problem und eine verständnisfrage dazu



sn4fu
09-10-2001, 15:45
hi, ich hab vor ein paar tagen angefangen, mich mit c zu beschäftigen, und hab inzwischen ein prob, das ich nicht durchschaue:

ich will das der user einen text eingibt, der in der variablen txt gespeichert wird und diese dann ausgegeben wird.

hier der source von dem programm:
---
#include <stdio.h>

void main()
{
char txt[11];

/* data input */
printf("enter text: ");
scanf("%10s",&txt);

/* data output */
printf("text: %s\n",txt);
}
---

so funktioniert das programm einwandfrei, der text wird eingelesen und dann auf dem screen ausgegeben.

allerdings hätte ich gerne, das dazu noch eine zahl eingelesen wird.
also sieht der source dann so aus:

---
#include <stdio.h>

void main()
{
char txt[11];
short x;

/* data input */
printf("enter text: ");
scanf("%10s",&txt);

printf("enter short number: ");
scanf("%d",&x);

/* data output */
printf("text: %s\n",txt);
}
---
nun wird jedoch nicht mehr der inhalt von txt ausgegeben, sondern nur noch
"text:"

nur versteh ich nicht, wieso das nicht mehr passiert.

und ne kleine verständnisfrage obendrein:

wenn ich in zeile 10 statt "scanf("%10s",&txt);" nur "scanf("%s",txt);" schreibe, dann kann ich für txt werte bis zur länge 15 eingeben, die dann auch korrekt ausgegeben werden. ab einer länge von 16 zeichen für txt bekomm ich dann erst die fehlermeldung "Ungültiger Maschinenbefehl". dabei dachte ich, durch "char txt[11];" hab ich für txt nur 11 zeichen im speicher reserviert. demnach hätte ich also schon ab 11 eingegeben zeichen doch die fehlermeldung bekommen müssen, oder?

stefan77
09-10-2001, 18:57
Hi

in C heisst char[11] nur das 11 Zeichen reserviert werden, unter C ist das aber nicht gleich bedeuten mit Speicherschutz.
Überlauf taucht erst auf wenn dieser zu groß ist. Dabei können sogar versehentlich andere Variablen im eigenen Segement überschrieben werden.

Der Programierer muß dafür sorgen das alles passt oder eine ensprechene Biblothek nutzen. gstring C++ String oder QString ...

SJW

P.S. über das UBB-"Codes" wird die Formatierung beibehalten.

sn4fu
10-10-2001, 00:13
aha, danke, damit wäre die verständnisfrage immerhin geklärt...

bleibt nur noch das praktische problem ;)

jgbauman
11-10-2001, 02:11
<BLOCKQUOTE><font size="1" face="Arial,Helvetica,Geneva">Zitat:</font><HR>nun wird jedoch nicht mehr der inhalt von txt ausgegeben, sondern nur noch "text:"
[/quote]
Diese Annahme ist falsch. Richtig ist: Der Inhalt von txt wird Ausgegeben, nur enthaelt txt jetzt ein leeres String.

Wieso?

Der Typ short hat (x86 - gcc) 2 Bytes, int hat 4. Der Formatparamter %d erwartet ein int. Mit &x uebergibst du scanf einen Zeiger auf ein short, aber es will eigentlich einen Zeiger auf ein int. Gibst Du als Zahl jetzt 5 ein sind das als int vier Bytes: 5 0 0 0.
Da x aber ein short ist und dafuer nur zwei Bytes reserviert sind ueberschreiben die beiden letzten Nullen die beiden ersten Bytes in txt. Da C-Strings nullterminiert sind und das erste char in txt nun Null ist, enthaelt txt nur noch ein String der Laenge Null == "". Gib mal als Text: 12 und als Zahl: 1766353224 ein ;-)
Benutze beim gcc die Option -Wall, dann kriegst du Warnmeldungen dazu.
<BLOCKQUOTE><font size="1" face="Arial,Helvetica,Geneva">Zitat:</font><HR> wenn ich in zeile 10 statt "scanf("%10s",&txt);" nur "scanf("%s",txt);" schreibe, dann kann ich für txt werte bis zur länge 15 eingeben, die dann auch korrekt ausgegeben
werden. ab einer länge von 16 zeichen für txt bekomm ich dann erst die fehlermeldung "Ungültiger Maschinenbefehl". dabei dachte ich, durch "char txt[11];" hab ich für txt nur 11
zeichen im speicher reserviert. demnach hätte ich also schon ab 11 eingegeben zeichen doch die fehlermeldung bekommen müssen, oder? [/quote]
Das Du Speicher auf dem Stack ueberschreibst sobald du mehr als 11 Zeichen (10+Nullbyte) in txt schreibts stimmt. Aber ein ueberschriebener Wert auf dem Stack muss ja keinen Fehler versursachen (z.B. wenn der Wert ab dieser Stelle im Programm gar nicht mehr benutzt wird). Daher kriegst Du halt erst ne Fehlermeldung, wenn Du was wichtiges ueberschreibts.

Weitere Anmerkungen:
Am Ende von main() fehlt: return 0;
Das &txt beim scanf liefert zwar den richtigen Wert, ist aber vom falschen Typ;

&txt ist ein (char (*)[11]) und nicht (char*).
Einfach txt ist ein (char*).

iGEL
16-10-2001, 23:14
Moin!

&gt; Weitere Anmerkungen:
&gt; Am Ende von main() fehlt: return 0;

Und es muss int main() heissen. Einfach nur main() ist zwar auch erlaubt, aber void main() ist verboten. ;)

cu iGEL

PS: Sorry, dass ich son altes Thema aufwärme.