String and char related question

Let's say I have a one big string which is coded with symbols like Morse Code. And i have declared every single letter as a morse code. But I need to make every single morse code equal to the right one letter. How should i declare it?
Hopefully the symbols have a space or comma after every alphabet character.
Use an std::map<char, std::string> const.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <map>

using namespace std;

int main()
{
    map<string,char>morseCode;

    morseCode[".-"]   = 'A';
    morseCode["-..."] = 'B';
    morseCode["-.-."] = 'C';
    morseCode["-.."]  = 'D';
    morseCode["."]    = 'E';
    morseCode["..-."] = 'F';
    morseCode["--."]  = 'G';
    morseCode["...."] = 'H';
    morseCode[".."]   = 'I';
    morseCode[".---"] = 'J';
    morseCode["-.-"]  = 'K';
    morseCode[".-.."] = 'L';
    morseCode["--"]   = 'M';
    morseCode["-."]   = 'N';
    morseCode["---"]  = 'O';
    morseCode[".--."] = 'P';
    morseCode["--.-"] = 'Q';
    morseCode[".-."]  = 'R';
    morseCode["..."]  = 'S';
    morseCode["-"]    = 'T';
    morseCode["..-"]  = 'U';
    morseCode["...-"] = 'V';
    morseCode[".--"]  = 'W';
    morseCode["-..-"] = 'X';
    morseCode["-.--"] = 'Y';
    morseCode["--.."] = 'Z';
    morseCode[" / "]  = ' ';

  string entirecode = ".... . .-.. .-.. --- / -.. .- .. .-.. -.-- 
/ .--. .-. --- --. .-. .- -- -- . .-. / --. --- --- -.. / .-.. ..- -.-. -.- / --- -. / - .... . 
/ -.-. .... .- .-.. .-.. . -. --. . ... / - --- -.. .- -.--";


     cout << morseCode["...."] << morseCode["."] << morseCode[".-.."] << morseCode[".-.."] 
     << morseCode["---"] << morseCode[" / "] << morseCode["-.."] << morseCode[".-"];
     cout << morseCode[".."] << morseCode[".-.."] << morseCode["-.--"] << morseCode[" / "];
     cout << morseCode[".--."] << morseCode[".-."] << morseCode["---"] << morseCode["--."] 
     << morseCode[".-."] << morseCode[".-"] << morseCode["--"] << morseCode["--"]
      << morseCode["."] << morseCode[".-."] << morseCode[" / "];
     cout << morseCode["--."] << morseCode["---"] << morseCode["---"] 
     << morseCode["-.."] << morseCode[" / "];
     cout << morseCode[".-.."] << morseCode["..-"] << morseCode["-.-."] 
     << morseCode["-.-"] << morseCode[" / "];
     cout << morseCode["---"] << morseCode["-."] << morseCode[" / "];
     cout << morseCode["-"] << morseCode["...."] << morseCode["."] << morseCode[" / "];
     cout << morseCode["-.-."] << morseCode["...."] << morseCode[".-"] << morseCode[".-.."] 
     << morseCode["."] << morseCode["-."] << morseCode["--."] << morseCode["."] 
     << morseCode["..."] << morseCode[" / "];
     cout << morseCode["-"] << morseCode["---"] << morseCode["-.."] << morseCode[".-"] 
     << morseCode["-.--"] << morseCode[" / "] << endl;




    return 0;
}


so this is the brutal code that i wrote just in order to do that challenge. but i need to know how can i optimize this program?
Last edited on
Haha, well you could have used an initializer like this to keep your map constant and to eliminate about 20 lines of code:

1
2
3
4
5
6
7
8
std::map <std::string, char> const morseCode 
  {{".-"  , 'A'}, {"-...", 'B'}, {"-.-.", 'C'}, {"-.." , 'D'},
   {"."   , 'E'}, {"..-.", 'F'}, {"--." , 'G'}, {"....", 'H'},
   {".."  , 'I'}, {".---", 'J'}, {"-.-" , 'K'}, {".-..", 'L'},
   {"--"  , 'M'}, {"-."  , 'N'}, {"---" , 'O'}, {".--.", 'P'},
   {"--.-", 'Q'}, {".-." , 'R'}, {"..." , 'S'}, {"-"   , 'T'},
   {"..-" , 'U'}, {"...-", 'V'}, {".--" , 'W'}, {"-..-", 'X'},
   {"-.--", 'Y'}, {"--..", 'Z'}, {"/"   , ' '}};


And then you could have used a stream object to loop over your space-delimited string of morse code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# include <string>
# include <map>
# include <sstream>

int main (int, char**) {
  std::map <std::string, char> const morseCode
    {{".-"  , 'A'}, {"-...", 'B'}, {"-.-.", 'C'}, {"-.." , 'D'},
     {"."   , 'E'}, {"..-.", 'F'}, {"--." , 'G'}, {"....", 'H'},
     {".."  , 'I'}, {".---", 'J'}, {"-.-" , 'K'}, {".-..", 'L'},
     {"--"  , 'M'}, {"-."  , 'N'}, {"---" , 'O'}, {".--.", 'P'},
     {"--.-", 'Q'}, {".-." , 'R'}, {"..." , 'S'}, {"-"   , 'T'},
     {"..-" , 'U'}, {"...-", 'V'}, {".--" , 'W'}, {"-..-", 'X'},
     {"-.--", 'Y'}, {"--..", 'Z'}, {"/"   , ' '}};

  using namespace std::string_literals;
  std::string entireCode = ""s + ".... . .-.. .-.. --- / -.. .- .. .-.. -.-- / ."
    + "--. .-. --- --. .-. .- -- -- . .-. / --. --- --- -.. / .-.. ..- -.-. -.- "
    + "/ --- -. / - .... .  / -.-. .... .- .-.. .-.. . -. --. . ... / - --- -.. "
    + ".- -.--";

  std::istringstream stream(entireCode);
  for (std::string token; stream >> token; ) {
    std::cout << morseCode.at(token);
  }

  std::cout << "\n";
}


As far as efficiency optimization, it's already (probably sufficiently) efficient.

Last edited on
The compiler will give me errors for using C++ 98 does it how something to do with my compiler?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <map>
#include <sstream>
using namespace std;

int main()
{
    map<string,char>morseCode;

    morseCode[".-"]   = 'A';
    morseCode["-..."] = 'B';
    morseCode["-.-."] = 'C';
    morseCode["-.."]  = 'D';
    morseCode["."]    = 'E';
    morseCode["..-."] = 'F';
    morseCode["--."]  = 'G';
    morseCode["...."] = 'H';
    morseCode[".."]   = 'I';
    morseCode[".---"] = 'J';
    morseCode["-.-"]  = 'K';
    morseCode[".-.."] = 'L';
    morseCode["--"]   = 'M';
    morseCode["-."]   = 'N';
    morseCode["---"]  = 'O';
    morseCode[".--."] = 'P';
    morseCode["--.-"] = 'Q';
    morseCode[".-."]  = 'R';
    morseCode["..."]  = 'S';
    morseCode["-"]    = 'T';
    morseCode["..-"]  = 'U';
    morseCode["...-"] = 'V';
    morseCode[".--"]  = 'W';
    morseCode["-..-"] = 'X';
    morseCode["-.--"] = 'Y';
    morseCode["--.."] = 'Z';
    morseCode[" / "]  = ' ';

   string_literals;
  string entirecode = ".... . .-.. .-.. --- / -.. .- .. .-.. -.-- /
 .--. .-. --- --. .-. .- -- -- . .-. / --. --- --- -.. /
 .-.. ..- -.-. -.- / --- -. / - .... .  / -.-. .... .- .-.. .-.. . -. --. . ... / - --- -.. .- -.--";

    istringstream stream(entirecode);


     for (string token; stream >> token; ) {
    cout << morseCode.at(token);
  }

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

It crashes at the beginning of the second word. I had to dit this program a bit to even be able to print it.

EDIT: So what I did realized that it can't print out the space correctly and I believe string literals was allowing me to do that, but i couldnt launch my program. Any ideas?
Last edited on
I would suggest you start by fixing the compile errors that should be generated by your compiler.

The problems are mostly from lines 38 - 41.

What type of variable is string_literals?

You need to properly enclose the string on line 39 through line 41 in quotes (both begin and end on each line) or use the escape character ('\') at the end of lines 39 and 40.

Last edited on
First, I found a typo (compile error) in my code snippet. I seem to be doing that frequently these days -- sorry -- just line 16 entirecode should be entireCode.

std::string_literals is a namespace that contains the definitions of literal operators that let you create literal std::strings, so that you can write "blah"s + "blah" -- instead of std::string("blah") + "blah". It saves a few characters on occasion, not so much here; probably I shouldn't have used it.

But if you're compiling with C++98, then you're sort of out-of-luck. That feature only exists from C++11 onward.

Uniform initialization (lines 6-13 in my snippet of code above) is available only since C++11.

Let's take that snippet I posted and make it more backwards-compatible.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# include <iostream>
# include <string>
# include <map>
# include <sstream>

typedef std::map <std::string, char> MorseTable;

static MorseTable make_morseCode_table() {
  MorseTable result;

  /* encoded A-Z in order. */
  std::string const encoded_alphabet[26] = {
    ".-"  , "-...", "-.-.", "-.." , "."  , "..-.", "--.", "....",
    ".."  , ".---", "-.-" , ".-..", "--" , "-."  , "---", ".--.",
    "--.-", ".-." , "..." , "-"   , "..-", "...-", ".--", "-..-",
    "-.--", "--.."};

  for(int i = 0; i < 26; ++i) {
    result[encoded_alphabet[i]] = (static_cast <char> (i) + 'A');
  }

  /* Add the space character. */
  result["/"] = ' ';

  return result;
}

int main (int, char**) {
  MorseTable const morseCode = make_morseCode_table();

  std::string const entireCode = std::string() + ".... . .-.. .-.. --- / -.. .- .. .-."
    + ". -.-- / .--. .-. --- --. .-. .- -- -- . .-. / --. --- --- -.. / .-.. ..-"
    + " -.-. -.- / --- -. / - .... .  / -.-. .... .- .-.. .-.. . -. --. . ... / "
    + "- --- -.. .- -.--";

    std::istringstream stream(entireCode);
    for (std::string token; stream >> token; ) {
      try {
        std::cout << morseCode.at(token);
      } catch (std::exception e) {
        std::cerr << "Unrecognized token \"" << token << "\"\n";
      }
    }

  std::cout << "\n";
}


You don't really need the try-catch, but it'll tell you if your morse-code sequence is wrong.
Last edited on
I am using C++16th version, but still your code gives me error and i cant really understand why.
Well, you're not using C++16, because it doesn't exist. Some compilers have preemptively added an option for C++17, so perhaps that's what you meant?

If you click the "Edit and Run" button at the top-right of the snippet I posted, you can see that it compiles and runs as expected.

Please share the exact error message you are getting, and the command-line with which you compiled your code.
Well i does work and does so perfectly. But my question is then which version of the software i am using since once i open the program it shows 16.01.

Btw, I am very thankful for all the help I can get it means a lot for me!
You're welcome. :)

But C++ is not software, it's just the language itself. C++ is standardized by an ISO/IEC committee which meets three or so times per year. Whatever they come to a consensus about defines what makes a correct C++ program. Every few years, they release a formal specification that describes the current version of C++. Compiler vendors are expected to update their software to comply with the standard.

For instance, we say C++11 to refer to the language described by the C++ standard revision released in 2011, named ISO/IEC 14882:2011.

The version number on your compiler or IDE has nothing to do with the language version it implements -- usually you can control which standard you want by passing an option to the compiler.
Hi,

So I gather you are using CodeBlocks 16.01. Goto the settings menu, select compiler options. Select which compiler you have at the top. Tick the box which says follow the C++14 standard. There are other boxes you should tick as well, as a minimum: the Wall option; the pedantic-errors option.

C++14 is the current standard, C++17 is due out in Feb 2017, but some compilers already implement some of it - notably GCC.

You can create your own tick boxes by right clicking: I also always use the -Wextra compiler flag. If using GCC, one could create an option for using the C++17 standard (-std=c++17)- but that is probably way too much at this stage.

There are other flags not turned on in GCC or clang despite using -Wall -Wextra -pedantic-errors, you can read about them here:

http://www.cplusplus.com/forum/general/183731/#msg899203

It's worth reading the manual, despite there being a zillion options:
https://gcc.gnu.org/onlinedocs/

One of the problems with CodeBlocks is that it does not seem to do background compilation. (Apart from that , it seems to be a good IDE) This is a very handy feature if one is learning. It tells you about errors as you type. IDE's such as QtCreator is one of several that can do this.

https://www.qt.io/ide/

Qt is an entire framework for making GUI applications - it might be a bit advanced for you right now, but could be a good thing to keep in mind for the future :+) Note: one doesn't have to do Qt apps when using QtCreator - can still do plain C++ console apps.

Good Luck !!
Good Afternoon, yupp you were right, in fact i tried looking into it but i couldnt find a place to tick for a C++14 so i chose C++11 and yeah it did make your code work mbozzi. I will definately check out more about stuff that is there.

So, TheIdeasMan, which complier would you recommend using? I have an option to get a free microsoft visual studio compiler since im now a first year student. Should I go for it?
Hi,

Realise the difference between an IDE (Integrated Development Environment) and a compiler. A compiler is a tool which forms part of the IDE, along with an editor, a debugger, profiler etc.

The C++14 option is in there for CB, I have the same version on my machine. Although it may depend on which version of the compiler you have installed - need at least v5.3 of gcc (or equivalent version of MinGW) IIRC. gcc is currently at version 6.1 But C++11 should be fine at this stage.

If you have free access to another IDE, then make use of that and your existing one. Try to use more than one compiler as well. GCC and clang are popular. clang can be integrated with VS , but apparently not GCC. With CodeBlocks one can choose which one to use. I am a Linux person, so I am not up with all the details of what happens in the MS world. In terms of the arms race between compilers, GCC seems to be ahead at the moment - it has more C++17 features, but as I said that is probably too advanced.

If you can try to get some exposure to Linux - it will be worth some brownie points for when you apply for a job. Linux is easy to download onto a memory stick, and one can have a go with the Live version without having to install it onto your HD/SSD

I've heard about Linux but I am deep into the shit with programming I want so much things to learn and I struggle so I will stay with Windows for a moment.
Topic archived. No new replies allowed.