C If Variable enthält

K

KnightArtorias

Gast
Guten Morgen zusammen,

bin neu im Forum und stell gleich mal eine Frage.

Ich bin grade in der Ausbildung zum Fachinformatiker / Systemintegration und beschäftige mich mit den Basics der Programmierung. Heute ist ein ruhiger Tag und ich dachte mir: "setzt du dich halt mal an die ganzen Übungen aus der BS und programmierst dich durch" läuft ganz gut nur jetzt hänge ich an einem Befehl den ich noch nicht kenne und vor einigen Minuten via Google gefunden habe.

Im Grunde will ich das wenn meine Variable ein bestimmtes Zeichen enthält, wie folgt gehandelt wird ansonsten eben so oder so.

Also:

Code:
If (Variable enthält)
{mach dies}
else
{mach das}

Erklärung: Das Programm überprüft ein Datum das der User eingibt. Bei dem Jahr soll er wenn ein Minus vorkommt ausgeben
das das Jahr vor Christus ist, ansonsten eben nach Christus.
Sieht bisher so aus:

Code:
#include <stdio.h>
#include<string.h>

int iTag, iMonat, iJahr;

int main()
{
    printf("Bitte geben Sie den Tag ein\n");
    scanf("%i",&iTag);

    printf("Bitte geben Sie den Monat ein\n");
    scanf("%i",&iMonat);

    printf("Bitte geben Sie das Jahr ein\n");
    scanf("%i",&iJahr);

    if(iTag > 0 && iTag < 32)
    {
        if(iMonat > 0 && iMonat < 13 )
        {
            if(strcmp(iJahr, "-") == 0)
            {
                printf("%i.%i.%i vChr.",iTag,iMonat,iJahr);
            }
            else
            {
                printf("%i.%i.%i nChr.",iTag,iMonat,iJahr);
            }
        }
        else
        {
            printf("Ungültiges Datum\n");
        }
    }
    else
    {
        printf("Ungültiges Datum\n");
    }
}

nach der Eingabe der drei Daten stürzt es jedoch ab, ergo hab ich also irgendwo nen Fehler eingebaut.
Wenn mir einer von euch helfen könnte, wäre ich euch sehr verbunden ^^
 
Wie wäre es mit
Code:
 if(iJahr < 0)
            {
                printf("%i.%i.%i vChr.",iTag,iMonat,iJahr);
            }
 
Du greifst mit nem string-operator auf einen integer zu, das kann so nicht funktionieren ;)
Da du das Jahr eh als Zahl einliest und C auch negative Zahlen kennt, kannst du einfach überprüfen ob iJahr < 0
 
Die Lösung ist einfacher als du denkst: Du definierst "iJahr" als Ganzzahl mit Vorzeichen, liest sie als Ganzzahl mit Vorzeichen ein und startest dann ein "strcmp"? Das geht so nicht. strcmp funktioniert nicht auf Ganzzahlen. Bei Tag und Monat triffst du doch auch sinnvolle Vergleiche.

Btw: Beachte bitte Fehlermeldungen. Jede nicht ganz dumme IDE kann Programme in einem "debug"-Modus kompilieren lassen, da stürzen die Programme nicht ab, wenn sie einen Fehler erzeugen, sondern bleiben an der Fehlerstelle stehen und geben dir dann in der IDE aus, was genau schiefgelaufen ist.

Noch ein paar Anmerkungen: Ich würde den 31.2.2017 eher nicht als gültig ansehen. Im nächsten Schritt könntest du also beachten, dass nicht jeder Monat 31 Tage hat :)
 
strcomp auf nen Integer funktioniert nicht. Wie wärs mit iJahr < 0 um zu schauen ob das Jahr negativ ist?

Die Vergleiche sind ungünstig und sollten alle im gleichen if erledigt werden:
Code:
if (iTag > 0 && iTag < 32 && iMonat > 0 && iMonat < 13 && )
{
  if (iJahr < 0)
  {
    ...vChr
  }
  else
  {
    ...nChr
  }
}
else
{
  ..ungültig
}
 
Vorab erst mal ein dicker Facepalm dafür das mir (iJahr < 0) nicht eingefallen ist ^^
Ja also nächster hätte ich Monate mit eingeschlossen das dies noch beachtet wird ^^

Danke an alle für eure schnellen und hilfreichen Antworten ^^
 
Hi,

kommentiere doch einfach mal alles aus und dann Schritt für Schritt wieder ein, damit dir klar wird, wo er auf die Nase fällt!

VG,
Mad

Edit: Leute, lasst ihn das doch selber erkennen! Eine fertige Lösung bringt doch Null Lerneffekt! :rolleyes:
 
mal ganz generell dürfte es hilfreich die Fehlermeldung beim absturz zu beachten, die ist oft selbsterklärend.
Viele IDEs bieten auch Debugging Tools extra zum Fehlersuchen an, das dürfte dir das leben auf dauer deutlich vereinfachen. :)
 
@Madman:
Das ist alles aber nicht fertig. Die verschiedenen Monatsunterscheidungen fehlen noch, das wird genug Arbeit.
 
jap, ist der nächste Schritt ^^
Aber solange ich kein goto benutze ist ja alles noch gut ^^
 
Hi,

@sdwaroc

es ging auch nicht darum, dass das ganze Programm fertig ist sondern darum, dass die Lösung seines aktuellen Problems fertig vorgekaut wird anstatt ihm Hilfestellung zu geben, wie er das Problem systematisch und sinnvoll selber lösen kann.

Das ist in der Programmierung deutlich sinnvoller.

VG,
Mad
 
KnightArtorias schrieb:
Aber solange ich kein goto benutze ist ja alles noch gut ^^

Ja, bis Du in C oder C++ wieder "goto" nehmen darfst, mußt Du noch 10 oder 20 Jahre hart arbeiten. Dann darfst Du es wieder feierlich verwenden.
 
​@Madman1209: Prinzipiell stimme ich dir zu, fertige Lösungen zu präsentieren finde ich auch unsinnig, weil der Lerneffekt dabei 0 bleibt. Es ist aber immer eine Gratwanderung zwischen "finds selbst heraus" und eine kleine Hilfe zu geben. Fertigen Quellcode posten ist zwar immer falsch, aber dein Ansatz war auch ein wenig ZU abstrakt für einen Anfänger. Bei Hilfestellungen sollte man nicht nur auf den Lerneffekt achten, sondern auch den Lernenden nicht überfordern.

@sdwaroc: Ich sehe keinen Vorteil darin, die Vergleiche in ein if zu packen. Laufzeittechnisch ist es dasselbe, dafür musst du es wieder müßig auseinandernehmen, wenn du die verschiedenen Tage der verschiedenen Monate berücksichten möchtest. Und Madman1209 hat recht: Bei fertigem Quellcode ist bereits alles fertig.

@blöderidiot: Mit dem Kommentar wurdest du mal deinem Namen gerecht ... Ein GOTO ist weniger problematisch als man denkt, das benutzen auch heute noch SEHR viele Programmierer - nur meist ohne es zu wissen. Jedes break, jedes continue, generell jede Abbruch-Anweisung ist meist nichts anderes als ein GOTO. Man benutzt es nicht mehr, weil es inzwischen lyrischere Begriffe gibt, die wesentlich einfacher deutlich machen, wo denn jetzt hingesprungen werden soll - unterm Strich benutzt es aber fast jeder Programmierer sogar regelmäßig.
 
Madman1209 schrieb:
Edit: Leute, lasst ihn das doch selber erkennen! Eine fertige Lösung bringt doch Null Lerneffekt! :rolleyes:

Der Fehler hat imo. keinen Lerneffekt. Er hat das ganz einfach übersehen^^

@TE: By the way, bin mir nicht sicher ob du strcmp zu 100% vom Ablauf verstanden hast. https://www.tutorialspoint.com/c_standard_library/c_function_strcmp.htm

0 kann nur das Ergebnis sein wenn strlen1 == strlen2. Abgearbeitet wird string_variable1[0] == string_varable2[0]? Falls ja, string_variable1[1] == string_varable2[1]?

Vergleichst du (Ganzzahl als String gespeichert) 1999 mit 199 wird bei den stringstellen[0]-[2] das temporäre Ergebnis 0. Beim vergleich von [3] wird dann die 9 von 1999 mit der Stringendekennung \0 von 199 verglichen. Ergo 9 > \0, => return value 1.

Keine Ahnung welchen Wissensstand du da hast :-D
 
So Leute, nochmals Danke für die ganzen Antworten.
Habe jetzt noch zusätzlich die Schaltjahr Abfrage eingebaut. Es sind ziemlich große If Abfragen und ich bin mir nicht sicher ob ich es wirklich gut gelöst habe oder ich das ganze eher sehr unsauber ist.

Was sagen die Fachleute ? :D

Code:
#include <stdio.h>

int iTag, iMonat, iJahr;

int main()
{
    printf("Bitte geben Sie den Tag ein\n");
    scanf("%i",&iTag);

    printf("Bitte geben Sie den Monat ein\n");
    scanf("%i",&iMonat);

    printf("Bitte geben Sie das Jahr ein\n");
    scanf("%i",&iJahr);

    if(iTag > 0 && iTag < 32 && iMonat > 0 && iMonat < 13)
    {
        if(iJahr%4 == 0 || iJahr%100 == 0 && iJahr%400 == 0)
        {
            if(iMonat == 2 && iTag < 30)
            {
                if(iJahr < 0)
                {
                    printf("%i.%i.%i vChr. ist ein gültiges Datum",iTag,iMonat,iJahr);
                }
                else
                {
                    printf("%i.%i.%i nChr. ist ein gültiges Datum",iTag,iMonat,iJahr);
                }
            }
            else
            {
                printf("%i.%i.%i ist kein gültiges Datum",iTag,iMonat,iJahr);
            }
        }
        else
        {
            if(iMonat == 2 && iTag > 28)
            {
                printf("%i.%i.%i ist kein gültiges Datum",iTag,iMonat,iJahr);
            }

            else
            {
                if(iJahr < 0)
                {
                    printf("%i.%i.%i vChr. ist ein gültiges Datum",iTag,iMonat,iJahr);
                }
                else
                {
                    printf("%i.%i.%i nChr. ist ein gültiges Datum",iTag,iMonat,iJahr);
                }
            }
        }
    }
    else
    {
        printf("%i.%i.%i ist kein gültiges Datum",iTag,iMonat,iJahr);
    }
}
 
iJahr%4 ist ausreichend....warum? Ihr macht nicht zufällig induktive Beweisführung in Mathematik? ;)
 
Haha da muss ich dich enttäuschen ^^ Ich habe auf einer Seite gelesen das wenn alle drei Bedienungen erfüllt sind oder wenn Bedingung 1 erfüllt ist und 2 nicht es sich um ein Schaltjahr handelt.
 
Hallo,

die Schaltjahrprüfung funktioniert nicht 100% korrekt, da bei dir zB. 1900 ein Schaltjahr wäre. (%100 und nicht %400)
Die Anzahl der Monatstage könnte man elegant über ein Array der Monatstage lösen [31,28,31,30,...]
In deinem Code ist zB. der 31.4 ein gültiges Datum.

LG,
hgader
 
Servus

in der C-Welt ist %d statt %i für Integers deutlich weiter verbreitet. Vor allem kann man mit scanf %i auch Hex-Zahlen einlesen. Das sollte man ev. berücksichtigen.

LG
 
Zuletzt bearbeitet: (ev. falsch)
Mal ein paar generelle Tipps:

-) Du solltest besser NICHT davon ausgehen, dass Programm-macher und Programm-User sich auf Anhieb bzgl. sinnvoller Eingaben verstehen (inkl. dem Fall von absichtlich dummen Eingaben). Was etwa, wenn der User bei der Eingabe vom Monat "Februar", "blabla" oder "*&02hehe" eingibt?

-) Nach gutem Programmierstil sollten alle Variablen initialisiert werden. Erst Recht, wenn ev. nie ein gueltiger Wert reingeschrieben wird (siehe obiger Punkt).

-) Die Schaltjahrbedingung schau dir nochmal gut an. Probier mal etwa 1900 aus ...

-) Probiere Code wiederzuverwenden. Dieselben printfs kommen bei dir ja x-mal vor -> einmal reicht vollkommen aus, und erspart dir langfristig auch eine Menge Wartungsarbeit.

-) Wenn ein Datum ungueltig ist, waers hilfreich, auch einen dezenten Hinweis zu geben was ungueltig ist.

-) Die meisten Nutzer wuerden eine einzige Eingabe der Form TT.MM.JJJJ (oder etwa MM.TT.JJJJ in Amerika) mehr zu schaetzen wissen

-) Datums-geschichten sind an sich irrsinnig komplex. Siehe die Schaltjahr-geschichte, siehe dass es kein Jahr 0 gibt, siehe dass es auch andere als den Gregorianischen Kalender gibt, siehe locales fuer Eingabeformate. Um all diese Schlupfloecher zu schliessen braucht man seeehr langen eigenen Code. Und deshalb nutzt man in professionellem Code fuer sowas vorgefertigte Bibliotheken, um das Rad nicht neu erfinden zu muessen.
 
Zuletzt bearbeitet:
Zurück
Oben