Permalänk
Medlem

Hjalp med c++

Hej,

Har föröskt skapa en morsekodskonverterare ( text ska översättas till morsekod) som en uppgift att lösa till programmering B C++.

Via inmatning av text ska programmet svara i morsekod.

Det jag behöver hjälp med är själva villkoret i switch-satsen, att få switch att skriva ut fler än ett case vid text inmatning tex: inmatning: hej blir .... . .---

och detta ska då vara kopplat till string på ngt sätt.

(Det räcker att enbart konvertera text till morse och tvärtom behövs ej.)

Är tacksam för all hjälp!

Gaya

här nedan följer kod:

#include <iostream>
#include <string>
#include "iodos.h"
using namespace std;

main()
{
dos_console();

strings;
string morses []= {".-", "-...", "-.-.", "-..", ".", "..-.",
"--.", "....", "..", ".---", "-.-", ".-..",
"--", "-.", "---", ".--.", "--.-", ".-.",
"...", "-", "..-", "...-", ".--", "-..-",
"-.--", "--..", ".--.-",".-.-", "---." };

string texts []= {'a','b','c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'y',
'y','x', 'z'};

dos_console();
int val, text, morse;

cout << "\n\t Vad vill du göra?\n\n\n\t (1) Översätta till morse\n\t (2) Översätta från morse\n\n\t";
cout << "\n Skriv in ditt val av alternativ: ";
cin >> val;

if ( val == '1' )
{
cout << "\n\n\n\t Översätta till morse\n---------------------------------------------------------------------------\n\t";
cout << "\n\n Skriv in text du vill översätta till morse: \n\n\t";
cin >> text;

switch(text){

case 'a': cout << ".-";
break;
case 'b': cout << "-...";
break;
case 'c': cout << "-.-.";
break;
case 'd': cout << "-..";
break;
case 'e': cout << ".";
break;
case 'f': cout << "..-.";
break;
case 'j': cout << ".---";
break;
case 'k': cout << "-.-";
break;
case 'l': cout << ".-..";
break;
case 'm': cout << "--";
break;
case 'n': cout << "-.";
break;
case 'o': cout << "---";
break;
case 'p': cout << ".--.";
break;
case 'q': cout << "--.-";
break;
case 'r': cout << ".-.";
break;
case 's': cout << "...";
break;
case 't': cout << "-";
break;
case 'u': cout << "..-";
break;
case 'v': cout << "...-";
break;
case 'w': cout << ".--";
break;
case 'x': cout << "-..-";
break;
case 'y': cout << "-.--";
break;
case 'z': cout << "--..";
break;
case 'å': cout << ".--.-";
break;
case 'ä': cout << ".-.-";
break;
case 'ö': cout << "---.";
break;
}
}
else
if ( val == '2' )
{
cout << "\n\n\t Översätta från morse\n\n\--------------------------------------------------------------------------\n\t";
cout << "\n\n\t Skriv in text du vill översätta från morse: \n\n\t";
cin >> morse;
}

cout <<"\n\n\t";
return 0;
}

Permalänk
Medlem

Omslut din switch-sats med en loop som stegar genom strängen:

for(int i=0;i<text.length();i++) { switch(text[i]) { /* ... */ } }

F.ö. hade jag nog använt din array morses istället för en switch-sats, ex.

cout << morses[text[i]-'a'];

Alternativt gör man om morses till en hash/map och har bokstaven som index. Sen är jag ganska säker på att du vill ha text som std::string, inte int. Resten av din kod är rätt dålig den med, det borde inte kompilera alls.

Permalänk
Medlem

Tack Takc för svar!

ok, ska testa...dessa sätt, men vad är en hash/map?

Ja, jag vet min kod kunde varit bättre men är total nybörjare inom området vill dock lära mig. Tycker dock att det är en ganska svår uppgift...

Vet att jag kanske istället borde använda mig av arrayer och nyttja stringsen men vet inte hur man ska börja...

Har dock hittat lösningen till uppgiften på nätet via bokenshemsida och den ser ut som nedan:

#include <iostream>
#include <string>
#include "iodos.h"
using namespace std;

char *tab[] = {".-", "-...", "-.-.", "-..", ".", "..-.",
"--.", "....", "..", ".---", "-.-", ".-..",
"--", "-.", "---", ".--.", "--.-", ".-.",
"...", "-", "..-", "...-", ".--", "-..-",
"-.--", "--..", ".--.-",".-.-", "---." };
char *kod(char c)
{
if (c == 'Å' || c == 'å')
c = 'z'+1;
if (c == 'Ä' || c == 'ä')
c = 'z'+2;
if (c == 'Ö' || c == 'ö')
c = 'z'+3;
if (c>='A' && c<='Z')
c = c -'A' + 'a';
if (c >= 'a' && c <='z'+3)
return tab[c-'a'];
else if (c == ' ' || c == '\t')
return " ";
else
return "";
}
int main()
{
dos_console();
char m[500], val;

cout << "\n\n\n\t Översätta till

morse\n---------------------------------------------------------------------------\n\t";
cout << "\n\n Skriv in text du vill översätta till morse: \n\n\t";
cin.getline(m, 500);
for (char *p=m; *p; p++)
cout << kod(*p) << ' ';
cout << endl;

cout <<"\n\n\t";
return 0;
}

Känns fel att använda denna dock då det säkert tydligt är ngt som min lärare skulle känna igen

Permalänk
Hedersmedlem

iodos.h tillhör inte någon standardiserad form av C eller C++, den är skriven av Jan Skansholm, vars bok du kopierat lösningen från. Filen är, liksom användningen av C-strängar och ascii i sig, gravt föråldrad.

Håll dig till STL-string, läs på hur du läser in med cin utan char-array, och använd en associativ datastruktur, t ex map<char, string> och map<string, char> för att enkelt översätta åt båda hållen. Glöm inte att får med sifforna och de skiljetecken som finns i morse.

Problemet är inte att läraren skulle känna igen Skansholms lösning. Problemet är att lösningen bara är marginellt bättre än din egen.

Visa signatur

Religion och vidskepelse är smittsamma psykiska sjukdomar, den biologiska motsvarigheten till datorvirus.
"-Pappa, pappa, idag firade vi födelsedag och hela dagis fick gå på McDonalds. - Vems födelsedag då? - En farbror som hette Lenin."

Permalänk
Medlem
Skrivet av Ulvenstein:

Problemet är inte att läraren skulle känna igen Skansholms lösning. Problemet är att lösningen bara är marginellt bättre än din egen.

Tveksamt. Sist jag kollade var det programmering man lärde sig, inte C++ eller STL. Metodiken i Skansholms lösning och den lösning du föreslår är densamma, och de är därför ekvivalenta ur kursmålens synpunkt.

Att det sen är snyggare, lättare och "bättre" C++ att använda STL är en helt annan sak.

Permalänk
Medlem

Tack så himla mkt för bra tips nu vet jag vart jag kan börja!

Permalänk
Medlem

Ps. gillar era profil bilder.ds

Permalänk
Medlem

main(c){for(;c=c?c:(c=toupper(getchar())-32)?c<0?1: "\x95#\x8CKa`^ZRBCEIQiw#S#nx(37+$6-2&@/4)'18=,*%.:0;?5" [c-12]-34:-3;c/=2)putchar(c/2?46-c%2:32);}

från codegolf på stackoverflow
Code Golf: Morse code - Stack Overflow

Visa signatur

weeeee

Permalänk
Hedersmedlem

Vad var poängen med att visa den koden? Den är ju fullständigt oläsbar och gör ingen nytta för TS som vill lära sig.

Permalänk
Medlem
Skrivet av Shimonu:

Vad var poängen med att visa den koden? Den är ju fullständigt oläsbar och gör ingen nytta för TS som vill lära sig.

Rolig grej, passande i sammanhanget?

Visa signatur

Vill du ha svar? Citera mig gärna.

Permalänk
Hedersmedlem
Skrivet av You:

Tveksamt. Sist jag kollade var det programmering man lärde sig, inte C++ eller STL. Metodiken i Skansholms lösning och den lösning du föreslår är densamma, och de är därför ekvivalenta ur kursmålens synpunkt.

Att det sen är snyggare, lättare och "bättre" C++ att använda STL är en helt annan sak.

Nej, metodiken är inte densamma. Skansholms lösning är ett fulhack på tillfälligheten att bokstäverna a-z ligger på rad i ascii-tabellen, och på så sätt kan användas som index i en array, något som han själv upptäckte inte funkar när å, ä och ö ska med.

Att returnera pekare på det sättet han gör det kan visserligen fås att funka i små, konstgjorda exempel, men det är inget man ska lära elever att göra eftersom det är en stor felkälla. I lite större program hade det varit ett helvete att jaga bortsprugna pekare som man inte riktigt vet vad de är eller var de kommer ifrån. Det är fulhack man kan kosta på sig i pyttesmå embeddedsystem för att spara lite tid och minne, men i alla andra sammanhang är det föråldrat, idag, precis som för 10-15 år sedan när boken kom ut.

Visa signatur

Religion och vidskepelse är smittsamma psykiska sjukdomar, den biologiska motsvarigheten till datorvirus.
"-Pappa, pappa, idag firade vi födelsedag och hela dagis fick gå på McDonalds. - Vems födelsedag då? - En farbror som hette Lenin."

Permalänk
Medlem
Skrivet av Ulvenstein:

Nej, metodiken är inte densamma. Skansholms lösning är ett fulhack på tillfälligheten att bokstäverna a-z ligger på rad i ascii-tabellen, och på så sätt kan användas som index i en array, något som han själv upptäckte inte funkar när å, ä och ö ska med.

Att returnera pekare på det sättet han gör det kan visserligen fås att funka i små, konstgjorda exempel, men det är inget man ska lära elever att göra eftersom det är en stor felkälla. I lite större program hade det varit ett helvete att jaga bortsprugna pekare som man inte riktigt vet vad de är eller var de kommer ifrån. Det är fulhack man kan kosta på sig i pyttesmå embeddedsystem för att spara lite tid och minne, men i alla andra sammanhang är det föråldrat, idag, precis som för 10-15 år sedan när boken kom ut.

Metodiken är densamma. Det Skansholm gjort "fel" är valet av lagringsstruktur.
Ersätt arrayen med en hashmap (där du faktiskt kan komma åt elementen enligt tecknens representation) så har du en fungerande lösning även för å, ä och ö. Att använda pekaren i sig för att iterera över strängen och komma åt rätt element i lagringsstrukturen är inget problem, så länge man ser till att objektet kan frigöras ordentligt (dvs. gör en kopia av pekaren och utför aritmetik på kopian).

Permalänk
Medlem

Gick samma kurs för nåt år sedan..
Postar min lösning (som antagligen inte på något sätt är optimal) i förhoppning om att du kan lära dig nåt av den.

#include <iostream> #include <string> void showMenu(); void convertToMorse(); void convertFromMorse(); void showMorseTable(); using namespace std; const short ARSIZE = 32; //definerar en struktur av typen morse som innehåller en signed int och en sträng struct morse { signed int asciiNum; string morseStr; //deklarerar och initierar en global vektor av morsetyper med namnet table, denna innehåller alla asciikoder för vardera gemen (a-z) samt åäö, ÅÄÖ och motsvarande morsekod }table[ARSIZE] = { {97, ".-"}, {98, "-..."}, {99, "-.-."}, {100, "-.."}, {101, "."}, {102, "..-."}, {103, "--."}, {104, "...."}, {105, ".."}, {106, ".---"}, {107, "-.-"}, {108, ".-.."}, {109, "--"}, {110, "-."}, {111, "---"}, {112, ".--."}, {113, "--.-"}, {114, ".-."}, {115, "..."}, {116, "-"}, {117, "..-"}, {118, "...-"}, {119, ".--"}, {120, "-..-"}, {121, "-.--"}, {122, "--.."}, {-122, ".--.-"}, {-124, ".-.-"}, {-108, "---."}, {-113, ".--.-"}, {-114, ".-.-"}, {-103, "---."} }; int main() { cout << "** Morsekodskonverterare **\n\n"; showMenu(); int choice; (cin >> choice).get(); while (choice != 4) { switch (choice) { case 1 : convertToMorse(); break; case 2 : convertFromMorse(); break; case 3 : showMorseTable(); break; default: cout << "\nFelaktigt alternativ!\n"; } showMenu(); choice = 4; (cin >> choice).get(); } return 0; } void showMenu() { cout << "\nHuvudmeny\n" << "1:\x94vers\x84tt till morse\n" << "2:\x94vers\x84tt fr\x86n morse\n" << "3:Visa morsekodstabellen\n" << "4:Avsluta\n" << "--------------------------------\n" << "Val: "; return; } void showMorseTable() { cout << "\nMorsekodstabellen:\n" << "------------------\n"; for (int c = 0; c < (ARSIZE-3); c++) cout << char(table[c].asciiNum) << " = " << table[c].morseStr << endl; return; } void convertToMorse() { string asciiIn; cout << "\n\n\x94vers\x84tt till morse\n" << "--------------------\n" << "Skriv in text som skall \x94vers\x84ttas till morsekod: "; getline(cin, asciiIn); for (int lcount = 0; lcount < asciiIn.size(); lcount++) asciiIn[lcount] = tolower(asciiIn[lcount]); cout << "\nMorsekod:\n"; for (int acount = 0; acount < asciiIn.size(); acount++) { //användarens inmatning jämförs tecken för tecken med asciikoden i table, om inmatningen matchar så skrivs morsesträngen ut på skärmen for (int mcount = 0; mcount < ARSIZE; mcount++) { if (int(asciiIn[acount]) == table[mcount].asciiNum) cout << table[mcount].morseStr << " "; } } cout << endl; return; } void convertFromMorse() { string morseIn; //morsekoden användaren matar in string asciiOut; //buffer för asciikoden som skall läggas till i utmatningen string morseString; //buffer för morsekod som skall översättas för varje tecken string resultStr; //den översättna morsekoden cout << "\n\n\x94vers\x84tt fr\x86n morse\n" << "--------------------\n" << "Skriv in morsekod som skall \x94vers\x84ttas till klartext: "; getline(cin, morseIn); for (int count = 0; count < morseIn.size(); count++) { //hittas "." eller "-" så läggs dessa in i buffervariabeln if (morseIn[count] == '-' || morseIn[count] == '.') morseString += char(morseIn[count]); else { for (int acount = 0; acount < ARSIZE; acount++) { //om inget morsetecken hittas antas att en hel morsekod lästs in if (table[acount].morseStr == morseString) asciiOut = char(table[acount].asciiNum); } resultStr += asciiOut; morseString = ""; asciiOut = ""; } } for (int acount = 0; acount < ARSIZE; acount++) { if (table[acount].morseStr == morseString) asciiOut = char(table[acount].asciiNum); } resultStr += asciiOut; cout << "\nKlartext:\n"; cout << resultStr << endl; return; }

Visa signatur

Ungos

Permalänk
Medlem
Skrivet av knug:

Gick samma kurs för nåt år sedan..
Postar min lösning (som antagligen inte på något sätt är optimal) i förhoppning om att du kan lära dig nåt av den.

Det är en relativt bra lösning, men struct-arrayen är lite "fulhack" (även om den kanske gjort sig bra i C) — en riktig hashmap är bättre. Metodiken är dock samma som Skansholms lösning. Att importera hela std-namespacet är väl lite onödigt också.

Permalänk
Hedersmedlem
Skrivet av You:

Det är en relativt bra lösning, men struct-arrayen är lite "fulhack" (även om den kanske gjort sig bra i C) — en riktig hashmap är bättre. Metodiken är dock samma som Skansholms lösning. Att importera hela std-namespacet är väl lite onödigt också.

Fortfarande inte samma metodik. Han hanterar teckentabellen helt och hållet i data, istället för som Skansholm, i kod.

Är du släkt med Skansholm, eller varför sitter du och försöker försvara smörjan?

Visa signatur

Religion och vidskepelse är smittsamma psykiska sjukdomar, den biologiska motsvarigheten till datorvirus.
"-Pappa, pappa, idag firade vi födelsedag och hela dagis fick gå på McDonalds. - Vems födelsedag då? - En farbror som hette Lenin."

Permalänk
Medlem
Skrivet av Ulvenstein:

Fortfarande inte samma metodik. Han hanterar teckentabellen helt och hållet i data, istället för som Skansholm, i kod.

Är du släkt med Skansholm, eller varför sitter du och försöker försvara smörjan?

Skansholm hanterar specialfallen i kod. Jag säger inte att det är bra, men i grunden har han samma metodik – lagra översättningar i en datastruktur och hämta rätt översättning till rätt tecken för varje tecken i indata. Att han sedan valt en extremt dålig struktur för problemet (detta kommer sig endast av det faktum att tecknen i indata inte ligger i följd i ASCII) är en annan sak, som gör att han måste ha en "översättning" från indata till lagringsstruktur.

Faktum är att han i princip implementerar en hashmap (på ett väldigt klumpigt sätt): Han översätter indata till unika nycklar som används för att kolla upp rätt värde i strukturen. Jag håller med om att det är fult gjort, och inget man bör ta efter, men det är fortfarande samma metodik:

Vanlig hashmap:

  1. Översätt indata till "unik" nyckel (hash)

  2. Leta upp nyckeln i datastrukturen

  3. Plocka ut värdet som hör till nyckeln

Skansholm:

  1. Översätt indata till unik nyckel (a-z avbildas på 0-25, åäö avbildas på 26-28)

  2. Leta upp nyckeln i datastrukturen

  3. Plocka ut värdet som hör till nyckeln

knug:

  1. "Översätt" indata till unik nyckel (i detta fallet en icke-operation; allt avbildas på ASCII-värdet sig själv)

  2. Leta upp nyckeln i datastrukturen

  3. Plocka ut värdet som hör till nyckeln

F.ö. dör även knugs version om man t.ex. byter teckenkodning, eller bestämmer sig för att använda unsigned chars istället. Magiska siffror är inte bra, 'å' är bättre än "-122".

Permalänk

Knackade på 5 minuter följande kod i c#, kan kanske ge något tips, även om implementeringen ser annorlunda ut i c.

class Morse { string fras; string translated; char[] bokstaver = new char[] { 'a', 'b', 'c' }; //o.s.v. string[] morse = new string[] { "..-", ".-.", "..-.." }; //o.s.v. public Morse(string fras) //konstruktor { this.fras = fras; } public string translate() //funktion { for (int i = 0; i < fras.Length; i++) { int counter = 0; while (fras[i] != bokstaver[counter]) { counter++; } translated += " " + morse[counter]; } return translated; } }

Visa signatur

Macbook pro 13", 4gb ddr3, core2duo 2,53ghz, nvidia 9400m

Permalänk
Medlem

Tyckte den kod jag sett var mycket oläsbar i vissa fall och gammal så jag skrev något eget.
Läser dock inte versaler.

#include <iostream> #include <string> using namespace std; int menu(); int main() { setlocale(LC_ALL,"swedish"); // För åäö char cLetterArr[] = {'a','b','c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'y', 'x', 'z', 'å', 'ä', 'ö', ' '}; // Sista sloten för mellanslag string sMorseArr[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".--.-", ".-.-", "---.", " "}; // Sista sloten för mellanslag string sText = ""; string sMorse = ""; int choice; choice = menu(); while(choice != 0) { system("CLS"); //Rensa skärmen switch(choice) { case 1: cout << "Text: "; getline(cin,sText); for(int i = 0; i < (int)sText.length(); i++) //löper över hela texten bokstav för bokstav { for(int j = 0; j < 30; j++) //löper över hela alfabetet { if(sText[i] == cLetterArr[j]) //kontrollerar vilken plats i arrayen { cout << sMorseArr[j] << " "; //skriver ut från samma plats i morse arrayen } } } cin.get(); cout << endl; break; case 2: cout << "Två mellanslag indikerar nytt ord." << endl; cout << "Morse: "; getline(cin,sText); sText += " "; //lägger till ett extra space för att inte det ska krasha på sista platsen i arrayen. for(int i = 0; i < (int)sText.length(); i++) { if(sText[i] == ' ') //kollar om det var slut på morse koden för den bokstaven. { for(int j = 0; j < 29; j++) // löper över morse arrayen { if(sMorse == sMorseArr[j]) // kollar vilken morse bokstav det var { cout << cLetterArr[j]; // skriver ut den på samma plats fån bokstavs arrayen } } sMorse = ""; // cleara if(sText[i+1] == ' ') // kollar om nästa slot är space. det indikerar att hela ordet är skrivet { cout << " "; i++; // } } else { sMorse += sText[i]; // lägger in tecknet från det man matade in. } } cin.get(); cout << endl; break; } choice = menu(); } return 0; } int menu() { int choice; cout << "1. Översätt text till morse" << endl; cout << "2. Översätt morse till text" << endl; cout << "0. Avsluta" << endl; cin >> choice; cin.ignore(); return choice; }