Issue with soundex project not returning all results

Hello,
I am a C++ programming student in need of help with an issue I am having with my code. When the the program runs in the console, I get the correct output for the 10 words entered. Then, I get the soundex code output for the first word entered but the following words cout 0000. We are not allowed to use STL's for this project. Thank you in advance for the help/code review.

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
86
87
88
89
90
91
92
93
94
95
96
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
123
124
125
126
127
128
#include<iostream>
 
using namespace std;

void soundex(char&); // function prototype for conversions      
                 
char arr[10][40];    //create a 10 row array 40 characters in length   
         
int main()
 {
 long r,row;         //r = row and row = row
 int countspace=0,   //skip spaces
     output,         //output to output 0 after the conversion
      c=0,
      col,
      col2;          //for array calculations 

 char reader,        //reading characters
      converter,     //letters for conversion
      firstletter,   //firstletter for the first letter of each name in the soundex
      notEnc,        //determines if the letter will be encoded
      alphaChecker;  //checks if character is a letter or numeral 
 long space=0;
      r=0;
 //long row4;

 
cout << "Enter 10 words to get their soundex codes" << endl;
for(int i=0; i<10; ++i)
 {
     cout << "What word do you wish to enter? : ";
     cin >> arr[i];
     //cout << endl;
 }
 //for(int j=0; j<10; ++j)
 for (int row2=0; row2 < 10; row2++)
 //for(row=0;row<=r;row++)
 {
 space++; //make sure the first character in the array is not a space
	
	if(reader==' '|| reader=='\n') 
	{
	
		if(countspace<1) {c=0; if(space!=1) r++; countspace++; }
		//to neglegt the space and to go to the next row in the arr after each name
	}
	else
	{
        if(isalpha(reader)) 
                {
                arr[r][c]=reader; c++; countspace=0;//save the name in the array
                }
	 
	}
 }
 
   for(row=0;row<=r;row++) //this loop for conversion and to call the conversion function
   //for (int row4=0; row4 < 10; row4++)
    {
		  
        firstletter=arr[row][0];         //location of the first letter
	    firstletter=toupper(firstletter);//convert the first letter to upper case
	    arr[row][15]=firstletter;        //put the first letter in its place [row][15]
        output=0;col2=16;             //location the first letter in the soundex;        
    for(col=1;col<15;col++)      //we started from 1 (col=1)to except the first letter
	  {
          converter=arr[row][col];          //assign converter to the location in array
	      converter=toupper(converter);     //to make converter capital
	      alphaChecker=converter;           //determin if the character is a letter
	      notEnc=arr[row][col-1];           //is the following letter the same 
	      notEnc=toupper(notEnc);           //converts character to upper case
      
	  if(col>0 && isalpha(alphaChecker))//*
     	  {
          soundex(converter);       //send converter to the function for conversion
		  soundex(notEnc);          //send notEnc to function for conversion
		  if(converter!=notEnc)     //check the following character
			  if(isdigit(converter) ) 
			  {
			  if(col2<19) 
			        {
			        arr[row][col2]=converter; col2++;
			        }
			  }   
		  
	      }
    
        }
 
  // for(int row3 = 0; row3 <= r;row3++)    //this loop to print both the name and its soundex 
 for (int row3=0; row3<10; row3++) //my test
   {//
	output=0;
        for(int col=0;col<19;col++)    //to print the name
            { //
	            reader=arr[row3][col];
	            if(isalnum(reader)) cout << reader;
	            if(col==14) cout<<" => ";    //to print => between name and soundex
	            if(col>15 && isdigit(reader))//how long is this
		        output++;                  
            }//

            output=4-output;   //to print 0 if the code is not long enough 
 
           while(output>0) 
            {//
            cout  << 0; output--; //Outputs zero's if the array contains nothing
            }//
            cout << endl;
            }//
    }
}

   void soundex(char& reader)       //the conversion function 
   {
    if(reader=='P'||reader=='B'||reader=='F'||reader=='V') reader='1';
    else                                                  
    if(reader=='C'||reader=='S' ||reader=='Q' ||reader=='K' ||reader=='G'||reader=='J' ||reader=='X'||reader=='Z') 
    reader='2';
    else 
    if(reader=='M'||reader=='N' ) reader='5'; 
    else 
    if(reader=='D'||reader=='T' ) reader='3';
    else 
    if(reader=='L' ) reader='4';
    else 
    if(reader=='R' ) reader='6';
  }
Last edited on
Don't put so many comments at the end of a line. It just makes code harder to edit or reformat. Put them before the line in question. Also, instead of multiplexing comments and code, prefer writing a single block of comment for a whole block of code. That improves readability. Normally I don't complain about style, but this was just too much.
And don't mix tabs and spaces. Use one or the other, but using both can generate confusion in certain circumstances.
{ // == completely useless comment. If someone doesn't know what braces do, they shouldn't be reading this.
Between line 18 and line 41, reader is not initialized, so the if is not valid.
Lines 77-79: Merge the three ifs into one: if (converter != notEnc && isdigit (converter) && col2 < 19)

Your if for soundex() can be made faster:
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
switch (reader){
	case 'P':
	case 'B':
	case 'F':
	case 'V':
		reader='1';
		return;
	case 'C':
	case 'S':
	case 'Q':
	case 'K':
	case 'G':
	case 'J':
	case 'X':
	case 'Z':
		reader='2';
		return;
	case 'M':
	case 'N':
		reader='5';
		return;
	case 'D':
	case 'T':
		reader='3';
		return;
	case 'L':
		reader='4';
		return;
	case 'R':
		reader='6';
}


That's all I can find for now.
Last edited on
Helios,
Thank you for the reply. What would be the best way to initialize reader? I have not touched C++ for 7 years and its not coming back as fast as I would like.
Thank you
You can use a lookup table for the SOUNDEX codes:
1
2
3
4
5
6
7
8
                           // ABCDEFGHIJKLMNOPQRSTUVWXYZ
const char SOUNDEX_codes[] = "A123E12HI22455O12623U1W2Y2";

char look_up_SOUNDEX_code( char letter )
  {
  if (!isascii( char )) return letter;
  return SOUNDEX_codes[ toupper( char ) -'A' ];
  }


You have waaaaay too many variables going on in there.
I think you need to step back (somewhere far enough away from the terminal that you need a pencil and paper to think about the program).

However, you should have two arrays: one for input and one for output. Don't mix them (it is confusing and error-prone).
1
2
char input_names [ 10 ][ 100 ];  // Things like "Wilkins" and "Avery"
char output_codes[ 10 ][ 5   ];  // Things like "W425" and "A160" 
You can easily print them side-by-side:
1
2
3
4
cout << "Code = Name\n";
for (int n = 0; n < 10; n++)
  if (input_names[ n ][ 0 ] != '\0')
    cout << output_codes[ n ] << " = " << input_names[ n ] << '\n';


Take a look at Wikipedia about the steps ("rules") to converting a name to SOUNDEX. Don't take shortcuts. Use some functions to do work if needed.

Though not critical, I also suggest that you be careful about how you name things. For example, a routine named "soundex" would be more likely expected to take a name and return the four-letter SOUNDEX code:
char* soundex( char* name );
Etc.

Hope this helps.
My guess, judging from the if, is that you should set reader to arr[row] at the start of the loop.

Seven years... That's longer than I've been into programming.
Last edited on
Thank you all for the continued assistance. I have taken your advice and started over on the program. I am a little confused on how to use the lookup table. I have started rewriting the code and any pointers would be greatly appreciated. Part of the assignment is passing the array or pointer to a function to do the conversions.
Thank you


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
#include<iostream>
using namespace std;

//lookup table for soundex codes
void soundex(char&);
const char SOUNDEX_codes[] = "A123E12HI22455O12623U1W2Y2";
char input_names [10][100];  // Things like "Wilkins" and "Avery"
char output_codes[10 ][6];  // Things like "W425" and "A160"

int main()
{

    for(int i = 0; i < 10; i++)
        {
        //char *word = input_names[i];
        cout << "Enter a word: ";
        cin >> input_names[i];
        cout << endl;
        }
    
    for(int j = 0;j<10;j++)
        {
        cout << input_names[j] << " => " << endl;
        }

} 



Last edited on
Use the LUT with the provided function. For example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...

int main()
  {
  char s[ 100 ];

  cout << "Enter a name> ";
  cin.getline( s, 100 );

  for (char* p = s+1; *p; p++)
    *p = look_up_SOUNDEX_code( *p );

  cout << "first pass: " << s << endl;

  return 0;
  }

The function verifies that the input character is in fact an alphabet letter ('A'..'Z' or 'a'..'z') then gets the corresponding value out of the LUT.

You could also just use the switch that helios suggested.
Topic archived. No new replies allowed.