Låssystem sekvens
Hej, jag ska göra ett låssystem nedanför. Jag har börjat lite på uppgiften men har fastnat och kommer inte vidare. Detta är vad jag har kommit fram till hittills:
Din kod gör inget för att avgöra om en inmatning är felaktig. Ska det t.ex. vara möjligt att gå från 0 till 2?
Nej det ska bara vara möjligt att gå från 0-1 och 1-2 osv men det är det jag inte kommer på hur jag ska avgöra om det är en felaktig inmatning.
Jag föreslår att koden ser ut ungefär så här:
if (strcmp(a, "unlock") == 0) {
if (n == 0) {
n = 1;
} else {
tala om för användaren att det är fel
}
och detta ska jag då göra på de 3 olika if funktion då och i else lägga till printf("invalid"); men jag måste också sätta in en printf("ok"); någonstans?
Är inte de fyra strcmp innan din while loop onödiga? Du sätter ju inget värde på a förrän du kommer in i while loopen.
Vidare är det farligt att endast deklarera en variabel utan att initiera den.
"ok" kan man skriva ut när man gör quit, om det inte har blivit fel innan dess.
okej, ska jag lägga till exempelvis a[8] = {0} isåfall?
Men nu blir det att den skriver invalid efter att jag har skrivit in någonting som inte är i rätt ordning, men programmet ska avgöra om det är ok eller inkorrekt efter jag har skrivit ett visst antal av orden och quit. Hur ska jag göra för att uppnå detta?
Visa hur koden ser ut nu.
Du man kan initiera en array på följande vis (som följer det du gjorde i inlägget tidigare):
char a[8] = "";
char a[8] = {0};
char a[8] = {0, 0, 0, 0, 0, 0, 0, 0};
alla dessa tre är ekvivalenta.
Du kan sätta en flagga om vi har gjort något invalid.
Och sedan i quit så printar du invalid om flaggan är satt, annars printar du ok.
Det kanske finns ett mer elegant sätt att göra det på?
med flagga menar du då att jag typ ger flaggan två värden exempelvis 0 och 1 där ett av värdena gör att det blir sant och den andra gör det inte sant?
Ja precis. Typ något liknande:
#include <stdio.h>
#define INVALID 0
#define VALID 1
int main()
{
int valid_sequence = VALID;
if(valid_sequence == VALID)
printf("Valid sequence");
else
printf("The given sequence is invalid.");
return 0;
}
Du får så klart strukturera upp de. Nu har du bara två fall, så det räcker egentligen med en define.
Okej men hur och vart ska jag sätta det i programmet och hur ska den avgöra om det är ok eller inte? För n kan gå från 0 -> 1 och 1 ->2 osv men inte motsatt håll.
Det är inte n du vill sätta. Istället för att printa i din while loop i alla conditions, så kan du göra det endast i quit.
Du sätter alltså flaggan så fort vi har gjort något fult och skriver ut rätt meddelande i quit beroende på om flaggan är satt eller inte.
Så någonting såhär?
Ja, men istället för dina printf, så sätter du nu:
val_seq = INVALID;
Det blir enklare att visa dig om du skriver in koden med {:}
För min del är jag för lat om jag ska vara ärlig för att skriva av din kod. :)
#include <stdio.h>
#include <string.h>
#define INVALID 0
#define VALID 1
int main ()
{
char a[8] = { 0 };
int n = 0;
int val_seq = VALID;
while (1) {
scanf ("%s", a);
if (strcmp (a, "unlock") == 0) {
if (n == 0) {
n = 1;
} else {
printf ("invalid\n");
}
}
if (strcmp (a, "open") == 0) {
if (n == 1) {
n = 2;
} else {
printf ("invalid");
}
}
if (strcmp (a, "close") == 0) {
if (n == 2) {
n = 3;
} else {
printf ("invalid");
}
}
if (strcmp (a, "quit") == 0) {
if (val_seq == VALID)
printf ("ok");
else
printf ("invalid");
break;
}
}
return 0;
}
Kod inklistrad i {:} och indenterad för att göra det enklare att läsa. /Dracaena
Menar du att jag ska byta ut de printf som jag har gjort // framför?
#include <stdio.h>
#include <string.h>
#define INVALID 0
#define VALID 1
int main ()
{
char a[8] = { 0 };
int n = 0;
int val_seq = VALID;
while (1) {
scanf ("%s", a);
if (strcmp (a, "unlock") == 0) {
if (n == 0) {
n = 1;
} else {
val_seq = INVALID;
}
}
if (strcmp (a, "open") == 0) {
if (n == 1) {
n = 2;
} else {
val_seq = INVALID;
}
}
if (strcmp (a, "close") == 0) {
if (n == 2) {
n = 3;
} else {
val_seq = INVALID;
}
}
if (strcmp (a, "quit") == 0) {
if (val_seq == VALID)
printf ("ok");
else
printf ("invalid");
break;
}
}
return 0;
}
Okej, men nu när jag testar de olika imput/output så fungerar alla förutom denna som blir invalid när jag kör programmet:
Kan du se varför det blir fel? :)
Denna buggen existerade innan också.
Prova gå igenom två iterationer när du tar unlock
lite osäker vad som är fel, har det något att göra med n?
När vi kör unlock för första gången så sätter vi , nu kör vi unlock igen, men eftersom så körs else blocket. Även om vi nu kör en valid sekvens, så har vi redan triggat flaggan.
Vi har alltså inte tagit hänsyn till att man kan gå:
current_state current_state
Utan programmet utgår ifrån att vi alltid går till en ny:
current_state next_state
Om vi ritar ett tillståndsdiagram ser det för tillfället ut så här:
Allt annat är invalid, men det borde egentligen vara:
Notera att jag inte skrev ut "quit" eftersom den inte tillger något till problemet.
om jag lägger till ett eller i if sasten och gör att kravet blir att n== 0 || n==1 kan det lösa problemet isåfall?
Ja, det löser unlock.
Hur blir det för de andra två? :)
för open borde det då bli:
n== 1 || n== 2
och för close:
n== 2 || n== 3?
prova :)
Vad tycker den nu att alla 4 blir?
Programmet funkar helt korrekt nu!
Tack så mycket för all hjälp!
Kul att vi var till hjälp, lycka till! :)
Det är direkt farligt att skriva
scanf("%s",a);
Det finns ingen som helst kontroll på hur lång strängen får vara. Du borde åtminstone skriva
scanf("%7s",a);