searching through a char array

Pages: 12
I want to make a program that the user enters a phone number like this: 1-800-ABC-DEFG and then spits out the number equivalent 1-800-222-3334. But I don't know where to start. Maybe char arrays? Anyone got an idea to start on?
Look at using switch case, char array, and strlen.
so far i have this, but the program just breaks at runtime. it only searches for A
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
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

int main()
{
    char Input[13];
    char Output[13] = "1-800-";
    char Two[] = "AaBbCc";
    char Three[] = "DdCcEe";
    char Four[] = "GgHhIi";
    char Five[] = "JjKkLl";
    char Six[] = "MmNnOo";
    char Seven[] = "PpQqRrSs";
    char Eight[] = "TtUuVv";
    char Nine[] = "WwXxYyZz";
    int counter = 6;
    char *searching;
    char Two2[] = "2";

    cout << "Enter a phone number in the following format: 1-800-ABC-DEFG" << endl;
    cin >> Input;

    while(counter != 14)
    {
        searching = strchr(Input,'A');

        if(searching != NULL)
        {
            Output[counter] = 2;
        }

        counter++;
    }

    cout << Output << endl;

    return 0;
}
since you are using C++
you could consider std::string rather than char array before std::string could not satisfy your application
Last edited on
yeah I probably should
Last edited on
You only need a lookup table.
1
2
                         /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
char ABC_to_123_lookup[] = "22233344455566677778889999";

If your input character is a letter, convert it to uppercase and subtract 'A' from it. That is the index of the correct digit in the lookup table.

I would also make a little function to do it for you, using the lookup table, and returning the translated character if it is alphabetic, or the same character if no lookup is needed (like for digits). I was going to just give it to you, but you can write it yourself. ;-)

Hope this helps.
I think Duoas has the best answer. Just do what he says and you're good to go.
Yeah that sounds really good im gonna try that. well this is what i came up on my own though:

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
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string Input;
    string Output = "1-800-";
    int counter = 6;
  
    cout << "Enter a phone number in the following format: 1-800-ABC-DEFG" << endl;
    cin >> Input;

    while(counter != 14)
        {
            if(Input[counter] == "A")//it wont let me compare this
            {
                Output = Output + "2";

                counter++;
            }

            if(counter == 9)
            {
                Output = Output + "-";

                counter++;
            }
        }

    cout << Output << endl;

    return 0;
}

Last edited on
shadowvillian wrote:
if(Input[counter] == "A")//it wont let me compare this

Use single qoute.
Use single quote.

correct you are.
Last edited on
w00t I figured it out:

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string Input;
    string Output = "1-800-";
    int counter = 6;

    cout << "Enter a phone number in the following format: 1-800-ABC-DEFG" << endl;
    cin >> Input;

    while(counter != 14)
        {
            if((Input[counter] == 'A')||(Input[counter] == 'B')||(Input[counter] == 'C'))
            {
                Output = Output + "2";

                counter++;
            }

            if((Input[counter] == 'D')||(Input[counter] == 'E')||(Input[counter] == 'F'))
            {
                Output = Output + "3";

                counter++;
            }

            if((Input[counter] == 'G')||(Input[counter] == 'H')||(Input[counter] == 'I'))
            {
                Output = Output + "4";

                counter++;
            }

            if((Input[counter] == 'J')||(Input[counter] == 'K')||(Input[counter] == 'L'))
            {
                Output = Output + "5";

                counter++;
            }

            if((Input[counter] == 'M')||(Input[counter] == 'N')||(Input[counter] == 'O'))
            {
                Output = Output + "6";

                counter++;
            }

            if((Input[counter] == 'P')||(Input[counter] == 'Q')||(Input[counter] == 'R')||(Input[counter] == 'S'))
            {
                Output = Output + "7";

                counter++;
            }

            if((Input[counter] == 'T')||(Input[counter] == 'U')||(Input[counter] == 'V'))
            {
                Output = Output + "8";

                counter++;
            }

            if((Input[counter] == 'W')||(Input[counter] == 'X')||(Input[counter] == 'Y')||(Input[counter] == 'Z'))
            {
                Output = Output + "9";

                counter++;
            }

            if(counter == 9)
            {
                Output = Output + "-";

                counter++;
            }
        }

    cout << Output << endl;

    return 0;
}
Good for you. Also you might want to check out Duoas's idea.

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 <iostream>
#include <string>
#include <cctype>

using namespace std;

int main()
{
    string lookup = "22233344455566677778889999";
    string Input;
    string Output;

    cout << "Enter a phone number in the following format: 1-800-ABC-DEFG" << endl;
    cin >> Input;
    Output = Input;

    for (int i=0; i<Output.length(); i++)
    {
        if (isalpha(Output[i]))
        {
            char c = toupper(Output[i]);
            Output[i] = lookup[c-'A'];
        }
    }
    cout << Output << endl;
    return 0;
}
Indeed. :D

Funny how the original poster's code is better than the code posted by the experienced C++ forumers. Hint: there is a potential vulnerability in your code, blackcoder. Your code is safe only assuming standard ANSI C-locale. If the environment is configured with a different locale, the code can be easily forced to access the array out of its bounds. Also relying on specific ASCII coding of letters is not theoretically correct - because how can you be sure that the system is actually using ASCII? Maybe the code will be run on some exotic embedded system that has its "own encoding"?

Such things should be done with a hashmap. Lookup table is "clever" but this is the kind of cleverness that often makes software crash in the most unexpected moments.
Last edited on
The only fail going on here is nonsense like that.

The locale is not changed anywhere in the program, but if it is a concern, you can easily write your own safe version of isalpha. That, and C++ requires certain characteristics to hold true for the character set -- such as requiring that the set of English letters with the same letter case be sequentially arranged in the character table. Sorry EBCDIC.

But again, even if that is the case, a proper lookup is still correct, and, as is the case in the original code, does not assume ASCII:
1
2
3
4
5
6
7
8
9
char ABC_to_123( char c )
  {
  static const char lookupA[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  static const char lookup0[] = "22233344455566677778889999";

  size_t index = std::find( lookupA, lookupA + 26, c ) - lookupA;

  return (index < 26) ? lookup0[ index ] : c;
  }

Hmm, what do you know? This is guaranteed to work on all random systems. Oh, notice how it is conservative with space -- a more important concern on embedded systems than your anti-cleverness nonsense.

"Such things should be done with a hashmap."
Are you kidding? Don't waste my time or memory. Wanna give me a hard time about excessive cleverness? You're a joke!


Oh, BTW, when have telephone keypads ever had letters other than "A-Z" on them? (Hint: never.)
[deleted]
Last edited on
Well while my solution might be simplier, Duoas's is a much smaller amount of code. his might even be more simplier but thats what i was able to come up with being less experienced.
@Duoas: your solution doesn't have the bug. I was not saying the lookup approach is generally bad, but by trying to make it short and clever (ok, the original code was long, I know), blackcoder introduced a very subtle bug into it. And finally the given code was worse than the original one. which was kinda funny, given the forum experience of blackcoder ;)

Many real vulnerabilities in programs are such small "almost-not-a-bug" things - they seem to be correct under some assumptions. But hackers like to attack in such a way to break these assumptions, thus breaking the code relying on them. Making the program correctness dependend on the codepage is one of such bugs waiting to happen. I've seen some Linux programs crashing when I changed the locale to UTF, so I've pointed this out. Be careful, and know what you are doing.


That, and C++ requires certain characteristics to hold true for the character set -- such as requiring that the set of English letters with the same letter case be sequentially arranged in the character table. Sorry EBCDIC.


Are you saying there are platforms where the C++ standard is not 100% implementable? Even worse: that there are platforms where C++ is not 100% implementable and Java is? (AS/400 for example that uses EBCDIC).


Are you kidding? Don't waste my time or memory


Sorry, but your corrected, flexible lookup is probably wasting much more cycles than the hashmap. :D And don't be kidding with the memory consumption. You saved like 50 bytes? Wow! You are an amazing optimizer! 50 bytes is nothing even on the most scarce in memory embedded systems.

BTW: Nice try with that lookup with STL, but it is still an ugly piece of code. That magic constants defending the end of the arrays are another possible problem waiting to happen (yes, someone removes a letter and voila, you have an off-by-one bug). I know I'm possibly niggling, but such small things too often show in Secunia reports. The original poster's code was still better and less ugly than that (ok, if was long, but anyway, what is the problem if something is long?)


Oh, BTW, when have telephone keypads ever had letters other than "A-Z" on them? (Hint: never.)


This is irrelevant to the problem I posted. This is like defending the old telnet buffer overflow vulnerability by saying "when does a remote terminal ever allow for more than 80 characters?"
Last edited on
maybe multimap of the stl could make the problem easier and safer?
it is a sorry that C++ don't have any built in hash table yet
[deleted]
Last edited on
I hope western!=rapidcoder

I don't think he/she could be the western, since the knowledge of them are not at the same level(apparently)
I am interesting about the idea of using hashtable to solve this question because I have the same
ideas as Duoas.
Besides, he pointed out something I never thought before
Last edited on
Pages: 12