C - Aus einem integer die zahlen einzeln auslesen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
me
Beiträge: 868
Registriert: 30.10.2005 00:14:23
Lizenz eigener Beiträge: GNU General Public License
Wohnort: Paderborn
Kontaktdaten:

C - Aus einem integer die zahlen einzeln auslesen

Beitrag von me » 26.09.2006 16:00:43

Hi,
Wollte gerade damit beginnen, einen weiteren programpart zu coden, allerdings bin ich auf ein mir unerklärliches phänomen gestoßen.

Hab das mal, damit es verständlich ist, in einen Beispielcode umgesetzt.

Code: Alles auswählen

#include <stdio.h>

int main(){
	int x = 0, zahl[20];
	printf("\n\tZahl eingeben, max. 20 Stellen: ");
	scanf("%i", &zahl);
	while(zahl[x] != '\0'){
		printf("\n%i\n",zahl[x]);
		x++;
	}
	return(0);
}
Ziel: Wenn man zum beispiel 123456 eingibt, soll er jede zahl in eine eigene reihe printen, ich will sie also, zwecks eines rechners, aufteilen.

Problem: er printed unerklärlicherweise: 123456
Anytime if we think we were right,
we were maybe wrong.

Benutzeravatar
esteel
Beiträge: 242
Registriert: 23.07.2002 11:06:25
Kontaktdaten:

Beitrag von esteel » 26.09.2006 16:13:43

das 12345 wird von scanf() als EINE Zahl eingelesen und auch entsprechend wieder ausgegeben..
i support free software: http://www.fsfe.org/en/fellows/esteel
a great free and opensource FPS game: http://nexuiz.com

Benutzeravatar
me
Beiträge: 868
Registriert: 30.10.2005 00:14:23
Lizenz eigener Beiträge: GNU General Public License
Wohnort: Paderborn
Kontaktdaten:

Beitrag von me » 26.09.2006 16:26:53

seit wann kann scanf auch zeichen ausgeben?
das er es als eine zahl einließt ist mir klar und mit zahl[x] spreche ich ja einen bestimmten bereich der variabel an
bei 123 müsste nämlich zahl[0] = 1 | zahl[1] = 2 sein etc
Anytime if we think we were right,
we were maybe wrong.

Spasswolf
Beiträge: 3472
Registriert: 30.11.2005 10:32:22
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Wald

Beitrag von Spasswolf » 26.09.2006 16:34:10

Lies die Zahl als String ein. Also

Code: Alles auswählen

char zahl[20]

Benutzeravatar
me
Beiträge: 868
Registriert: 30.10.2005 00:14:23
Lizenz eigener Beiträge: GNU General Public License
Wohnort: Paderborn
Kontaktdaten:

Beitrag von me » 26.09.2006 16:37:08

auch eben probiert, das endet in einem speicherzugriffsfehler wenn ich beim printf dann auch einen string angebe und wenn ich es beim printf beim int belasse:

Code: Alles auswählen

Bitte geben Sie die Zahl ein (max. 20 Stellen!): 234

50
51
52
End.
find ich bisschen komisch.
Anytime if we think we were right,
we were maybe wrong.

Benutzeravatar
esteel
Beiträge: 242
Registriert: 23.07.2002 11:06:25
Kontaktdaten:

Beitrag von esteel » 26.09.2006 16:41:06

me hat geschrieben:seit wann kann scanf auch zeichen ausgeben?
das er es als eine zahl einließt ist mir klar und mit zahl[x] spreche ich ja einen bestimmten bereich der variabel an
Natürlich gibt scanf keine Zeichen aus.. ich meinte scanf liest wohl den integer Wert in zahl[0] und das wird später auch so ausgegeben. Ich kanns gerade nicht testen aber ich bin mir sicher deine Schleife wird nur einmal durchlaufen.
i support free software: http://www.fsfe.org/en/fellows/esteel
a great free and opensource FPS game: http://nexuiz.com

Benutzeravatar
armin
Beiträge: 2682
Registriert: 17.03.2005 11:49:14

Beitrag von armin » 26.09.2006 17:07:39

me hat geschrieben:auch eben probiert, das endet in einem speicherzugriffsfehler wenn ich beim printf dann auch einen string angebe und wenn ich es beim printf beim int belasse:

Code: Alles auswählen

Bitte geben Sie die Zahl ein (max. 20 Stellen!): 234

50
51
52
End.
find ich bisschen komisch.
Ajo, du bekommst jetzt halt die ASCII-Codes ausgegeben ;)
Formerly known as Trigger.
HP 8510p - Debian Sid
Mitglied des Debian-KDE-Teams

Benutzeravatar
Frosch6669
Beiträge: 163
Registriert: 02.07.2003 23:16:49
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Frosch6669 » 26.09.2006 17:13:01

moin,
also soweit ich das weißt hast du ja ein eindimensionales array erstellt mittels zahl[20], welches zwanzig integer werte aufnehmen kann, wie mein vorredner, sprichst du einzelne zellen mittes z.b. zahl[3] an, also viertes feld.
ich würde eine schleife schreiben, die von i=0 - 19 geht in der du immer die ausgabe zahl machen. wenn das nicht klappt kannst du versuchen die zahl nicht als ganzes einzulesen, sondern egebfalls mittels schleifen und die werte dann ein array schreiben.
hoffe das hilft..
mfg
frosch

Benutzeravatar
me
Beiträge: 868
Registriert: 30.10.2005 00:14:23
Lizenz eigener Beiträge: GNU General Public License
Wohnort: Paderborn
Kontaktdaten:

Beitrag von me » 26.09.2006 17:54:37

möchte ja die quersumme von der eingegebenen zahl bilden, dafür brauche ich jede zahl einzeln und ja ich habe doch soweit eine schleife die sie eigentlich rausfiltern sollte und ich speichere es in dem eindimensionalen array.
Anytime if we think we were right,
we were maybe wrong.

aspettl
Beiträge: 318
Registriert: 15.02.2006 22:05:37
Lizenz eigener Beiträge: MIT Lizenz
Kontaktdaten:

Beitrag von aspettl » 26.09.2006 18:19:06

Du solltest nochmal nachlesen, was genau der Unterschied von integer und char ist, ebenso wie Arrays behandelt werden.
Die Vorredner haben da auch einiges angedeutet, aber ich bin nicht sicher, ob es bei dir ankam.

Ich denke wir brauchen nicht alternative Lösungen zu erläutern, das Problem ist ja nicht der Algorithmus, sondern die Umsetzung. Einen besseren Algorithmus kann man immer noch programmieren, wenn man es verstanden hat.
(Zu deinem Quersummenproblem gibt es hier ein paar verschiedene Lösungen, falls es interessiert: http://www.thescripts.com/forum/thread510983.html )

Gruß
Aaron

Spasswolf
Beiträge: 3472
Registriert: 30.11.2005 10:32:22
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Wald

Beitrag von Spasswolf » 27.09.2006 11:23:22

So geht's zum Beispiel mit der Quesumme:

Code: Alles auswählen

#include<stdio.h>
#include<string.h>
#define ASCII_OFFSET 48
int main(void)
{
char zahl[100];
int i,Quersumme=0;
printf("%s\n","Geben sie eine Zahl ein");
scanf("%s",zahl);

for(i=0;i<strlen(zahl);i++)
 {
 printf("%c\n",zahl[i]);
 }

for(i=0;i<strlen(zahl);i++)
 {
 Quersumme+=(zahl[i]-ASCII_OFFSET);
 }
printf("Quersumme = %d\n",Quersumme);

return 0;
}

Edit: Das hat sich mit dem Link von aspetti ja schon erledigt.

Benutzeravatar
me
Beiträge: 868
Registriert: 30.10.2005 00:14:23
Lizenz eigener Beiträge: GNU General Public License
Wohnort: Paderborn
Kontaktdaten:

Beitrag von me » 27.09.2006 18:30:59

ah jetzt verstehe ich auch gleich, wie das eine ergebnis bei 234 mit dem 50,51,52 zustande kam.
Vielen Dank.
Anytime if we think we were right,
we were maybe wrong.

Benutzeravatar
deadeye
Beiträge: 561
Registriert: 14.04.2004 15:32:18
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Ukio, rechts hinterm Feld
Kontaktdaten:

Beitrag von deadeye » 27.09.2006 18:49:24

Spasswolfs Variante ist ja ganz nett, aber noch optimierbar.
Was ist wenn jemand keine Zahlen sondern Buchstaben eingibt?
Und ich würde das in einer Schleife abhandeln(mir ist klar, das war nur Beispielcode zum Verdeutlichen).
Wegen der Buchstaben: ein einfaches if in der Schleife zum prüfen ob der gerade gelesene char zwischen 48 und 57 (inklusiv) liegt, wäre ein Anfang.

Deutlich sauberer und fehlerunanfälliger wäre aber, wenn Du wie Spasswolf per scanf einen String einließt, den mit atoi(), besser strtol(), in eine Zahl wandelst und dann mit Integer-Division und dem dabei entstehendem Rest an die einzelnen Stellen gehst.
Beispiel: anzunehmender Wert: "569"

Code: Alles auswählen

569 / 1  =  569 Rest = 0
569 / 10 =  56  Rest = 9
56  / 10 =  5   Rest = 6
5   / 10 =  0   Rest = 5
Damit hast Du implizit das Problem gelöst, wenn jemand Buchstaben eingibt, weil dann beim Umwandeln des Strings in eine Zahl schon 0 (atoi) rauskommt, bzw. mit strtol kriegst Du es besser raus, weil da hast Du eine bessere Fehlerprüfung(siehe man strtol).

Gruß
deadeye

P.S.: Ich habe mit Absicht keinen Beispielcode angegeben, der OP will ja auch noch ein wenig Gehirnschmalz reinstecken.

Child of Bodom
Beiträge: 79
Registriert: 13.03.2006 01:02:35

Beitrag von Child of Bodom » 27.09.2006 19:00:58

Das Berechnen der Quersumme funktioniert natürlich auch mit int-Variablen. Nachteil ist, dass der Zahlenbereich kleiner ist (20 Stellen ist schon sehr viel ;))

Code: Alles auswählen

#include <stdio.h>

int main()
{
	int quersumme=0;
	int zahl;
	int tmp;
	printf("Bitte Zahl eingeben: ");
	scanf("%d",&zahl);
	tmp = zahl;
	while (tmp!=0)
	{
		quersumme = quersumme + tmp%10;
		tmp = tmp/10;
	}
	printf("Die Quersumme von %d ist %d\n",zahl,quersumme);
	return 0;
}

Benutzeravatar
deadeye
Beiträge: 561
Registriert: 14.04.2004 15:32:18
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Ukio, rechts hinterm Feld
Kontaktdaten:

Beitrag von deadeye » 27.09.2006 19:34:43

Das ist in etwa das was ich sagen wollte und da fällt mir auf, dass scanf() ja auch Zahlen einlesen kann, somit der Umweg über atoi() oder strtol() nicht nötig ist. Was macht scanf(), wenn man als Format-Argument %d gibt, aber Buchstaben eingegeben werden?

Child of Bodom
Beiträge: 79
Registriert: 13.03.2006 01:02:35

Beitrag von Child of Bodom » 27.09.2006 19:44:24

deadeye hat geschrieben:Was macht scanf(), wenn man als Format-Argument %d gibt, aber Buchstaben eingegeben werden?
Keine Ahnung, was da intern vorgeht, aber hier mal die Ausgabe zu meinem Programmcode:

Code: Alles auswählen

Bitte Zahl eingeben: f
Die Quersumme von -1077931732 ist -40

Bitte Zahl eingeben: 4f3
Die Quersumme von 4 ist 4
8O 8O 8O

EDIT
Sorry deadeye, dass ich deinen Vorschlag verraten habe. Habe nicht mehr aktualisiert, bevor ich meinen Beitrag geschrieben habe und habe somit deinen nicht gelesen.

Benutzeravatar
deadeye
Beiträge: 561
Registriert: 14.04.2004 15:32:18
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Ukio, rechts hinterm Feld
Kontaktdaten:

Beitrag von deadeye » 27.09.2006 20:47:53

Grade mal nen Test gemacht:
scnaf() ließt die Eingabe so weit wie möglich als Zahl und schreibt was es bis dahin lesen konnte in den Integer der übergeben wird. So kommt die 4 bei Dir zustande, wenn Du 4f3 eingibst. Kann er gar keine Zahl aus der Eingabe lesen, lässt er den übergebenen int unangetastet, daher kommt bei Dir die -10... denn das ist dann ein zufälliger Wert im Speicher.
Daher bietet es sich evtl. doch an, die Zahl als String einzulesen und dann mit strtol umzuwandeln, dann weiß man wenigstens, dass der Benutzer Müll eingegeben hat.

Und die Lösung hast Du ja nicht wirklich "verraten", sondern nur etwas ausführlicher dargestellt. Ich war auch einfach ein wenig zu schreibfaul, das in C hinzupinseln.
Der OP wird sich freuen.

Antworten