Forum: Mikrocontroller und Digitale Elektronik Prüfen ob Zahl


von Eric (Gast)


Lesenswert?

Was ist bitte an meinem Code falsch???
er soll einmal fehler sagen wenn es keine zahl ist im string/array

...

char newnum[16] = {0};
newnum="123453";

for(int i=0; i<16; i++)
{
if ((!(newnum[i] > 47 && newnum[i] < 58)))
{
  printf("Falsche Eingabe");
  while(1);
}
else
{
...

von Uhu U. (uhu)


Lesenswert?

Versuchs mal so:

   if (!('0' <= newnum[i] && newnum[i] <= '9'))

Was soll das:

   while(1);

Da kommt er nur durch reset wieder raus.

von gast (Gast)


Lesenswert?

ctype.h
isdigit

von Rolf Magnus (Gast)


Lesenswert?

> Was ist bitte an meinem Code falsch???

Die Zuweisung an ein Array.

> char newnum[16] = {0};
> newnum="123453";

Einem Array kann man nichts zuweisen. Deshalb wird der Compiler dir hier 
eine Fehlermeldung ausspucken.

von vergessen... (Gast)


Lesenswert?

@ Uhu
Man muss doch davon ausgehen das newnum ein String ist.
Also werden die Zahlen nicht als "Zahl" sondern als "Zeichen" abgelegt.

Von wo bis wo gehen die Ziffern 0-9 in Deinem Zeichensatz ?

von Juergen (Gast)


Lesenswert?

Deine Zahl ist nur sechs Zeichen lang, du pruefst aber 16.

von jürgii (Gast)


Lesenswert?

er prüft eigentlich genau das erste Elemnt seiner Array auf die 
Bedingung (if-Anweisung), weil das  Programm dann nicht mehr aus der 
while-Schleife rauskommt :)

von Hc Z. (mizch)


Lesenswert?

1
 char newnum[16] = {0};
2
 newnum="123453";

In der zweiten Zeile muss doch eine Fehlermeldung kommen.  Denn Du 
versuchst, newnum die Adresse eines Strings zuzuweisen, newnum ist aber 
kein Pointer.  Warum verschweigst Du uns die?
1
strcpy(newnum, "123453")

von Juergen (Gast)


Lesenswert?

@jürgii Nein, bei den ersten 6 kommt er da nicht hin, erst bei \0 
danach.

von Uhu U. (uhu)


Lesenswert?

vergessen... schrieb:
> @ Uhu
> Man muss doch davon ausgehen das newnum ein String ist.
> Also werden die Zahlen nicht als "Zahl" sondern als "Zeichen" abgelegt.
>
> Von wo bis wo gehen die Ziffern 0-9 in Deinem Zeichensatz ?

Für ASCII gilt: '0' == 0x30 ... '9' == 0x39

Aber das mußt du garnicht wissen, wenn duch char-Konstanten benutzt.

Es gibt übrigens auch andere Zeichencodierungen, als ASCII. Wenn man 
char-Konstanten benutzt, sorgt der Compiler dafür, daß die richtigen 
Werde dafür eingesetzt werden.

von Karl H. (kbuchegg)


Lesenswert?

Uhu Uhuhu schrieb:
> vergessen... schrieb:
>> @ Uhu
>> Man muss doch davon ausgehen das newnum ein String ist.
>> Also werden die Zahlen nicht als "Zahl" sondern als "Zeichen" abgelegt.
>>
>> Von wo bis wo gehen die Ziffern 0-9 in Deinem Zeichensatz ?
>
> '0' == 0x30 ... '9' == 0x39

Muss man aber eigentlich auch nicht wissen.
* man kann ruhig '0' und '9' benutzen
* isdigit() erledigt das alles in einem Aufwasch

von Werner B. (werner-b)


Lesenswert?

> * isdigit() erledigt das alles in einem Aufwasch

und ist portabel (unabhängig vom Zeichensatz (ASCII EBCDIC etc.))

von Uhu U. (uhu)


Lesenswert?

Die Abfrage

    if (!('0' <= newnum[i] && newnum[i] <= '9'))

ist auch portabel und unabhängig vom Zeichensatz. (Auf die Schnapsidee, 
die Ziffern nicht zusammenhängend zu codieren, kam bisher keiner und das 
wird wohl so bleiben.)

von Marcus K. (marcusk)


Lesenswert?

> if (!('0' <= newnum[i] && newnum[i] <= '9'))
sieht mir irgendwie schwer lesbar aus

if (( newnum[i] < '0' || newnum[i] > '9'))

von Stephan V. (orca)


Lesenswert?

Also ich find Marcus Variante auch leichter lesbar, auch wenn mich da 
die Doppelklammer noch etwas stört ;) (Stichwort De Morgansche Gesetz)

Das eigentliche Problem ist aber die for-Schleife, die nicht erkennt, 
daß das String aus ist.

fix:
for (int i=0; (i<16) && (newnum[i] != 0x00); i++)

von Karl H. (kbuchegg)


Lesenswert?

Das eigentliche Problem ist, dass man bei Arbeiten mit einem String 
Indizes tunlichst vermeiden sollte. So was wird meistens nur umständlich 
und langsam. Dazu kommt, dass man sich durch die Indexarithmetik einen 
zusätzlichen Datentyp ins Boot holt, von dem a priori nicht klar ist, 
wie man ihn dimensionieren soll. Macht man einen unsigned char, dann hat 
man zwar (auf einem AVR) schnelle Arithmetik, ist aber auf eine maximale 
Stringlänge von 255 Zeichen limitiert. Macht man einen unsigned int, so 
hat man (zusätzlich zur ohnehin notwendigen Arithmetik beim Zugriff über 
den Index) auch noch einen zusätzlichen 16 Bit Inkrement mit im Boot. 
Die maximale Stringlänge von 65535 Zeichen kann man meist verschmerzen.
All das kann man aber vermeiden, wenn man Stringbearbeitung nicht auf 
Indizes, sondern auf Pointer aufbaut: Kein zusätzlicher Datentyp, 
maximale Stringlänge ist durch eine Systemkonstante (nämlich die sizeof 
eines Pointers) festgelegt.
1
  char* pCharacter = newnum;
2
  while( *pCharacter != '\0' ) {
3
    // mach was mit *pCharacter
4
    pCharacter++;
5
  }

Voraussetzung ist natürlich, dass der String von Anfang an schon richtig 
im Speicher steht. Programmintern ist das normalerweise kein Problem, 
lediglich an I/O Schnittstellen muss man da ein wenig Sorgfalt walten 
lassen. Aber das muss man bei I/O sowieso immer.

(Und immer daran denken, dass ein nuwnum[i] auch nicht gratis 
daherkommt)

von Uhu U. (uhu)


Lesenswert?

Stephan Veigl schrieb:
> Also ich find Marcus Variante auch leichter lesbar,

Das mag ja sein. Mein Motiv, das so zu schreiben war ganz einfach, daß 
ich dem OP nicht noch eine weiter Hürde aufbauen wollte und deswegen 
seine Logik benutzt habe.

Daß die newnum[i] "innen" stehen, hat mit meiner Art zu tun, wie ich mir 
derlei Konstellationen bildlich vorstelle, wenn ich den Ausdruck 
formuliere.

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
Noch kein Account? Hier anmelden.