Noobish C Fail - 'Permission Denied' - recreating Soundex code

Associate
Joined
27 Jan 2005
Posts
1,013
Location
Nr. Norwich, Norfolk
Hey guys,

The lastest episode in the saga of my wrestle to get to grips with C revolves around my inability to handle arrays.

I've been tasked with recreating the Soundex code. This involves several stages - removing vowels from a set of characters, removing double letters, and then translating it into a numeric code. :eek:

However, that all sounds pretty daunting, so to get to grips with how arrays work I've taken one task - removing vowels - and started trying to write a program that does just that and that alone, printing the output. However, I seem unable to get something that doesn't yield a 'Permission Denied' error. I'm assuming I'm grossly misunderstanding something along the way. :o

So far I have:

Code:
#include <stdio.h>
#include <string.h>
#include <math.h>

void devowel(char *B) {
  int i=1;
  int k=1;
  char a[27];/*This is entirely for reference. 26 letters...including 'ender'.*/
  a[0] ='A';
  a[1] ='B';
  a[2] ='C';
  a[3] ='D';
  a[4] ='E';
  a[5] ='F';
  a[6] ='G';
  a[7] ='H';
  a[8] ='I';
  a[9] ='J';
  a[10] ='K';
  a[11] ='L';
  a[12] ='M';
  a[13] ='N';
  a[14] ='O';
  a[15] ='P';
  a[16] ='Q';
  a[17] ='R';
  a[18] ='S';
  a[19] ='T';
  a[20] ='U';
  a[21] ='V';
  a[22] ='W';
  a[23] ='Y';
  a[24] ='X';
  a[25] ='Z';
  a[26] ='\0';
  //char B[20]; /*This array will hold the input*/
  /* B[20]='\0'; */
  scanf ("%s",B);
  for (i=0;i<=19;i++) {
    if (B[i]==a[0]) {
      for (k=0;k<=19;k++){   
		B[k]=B[k+1];
		}
	if (B[i]==a[4]) {
		for (k=0;k<=19;k++){   
		B[k]=B[k+1];
		}
    } 
	if (B[k]==a[8]) {
      		for (k=0;k<=19;k++){   
		B[k]=B[k+1];
		}
    } 
	if (B[k]==a[14]) {
      		for (k=0;k<=19;k++){   
		B[k]=B[k+1];
		}
    } 
	if (B[k]==a[20]) {
      		for (k=0;k<=19;k++){   
		B[k]=B[k+1];
		}
    }
  }
  printf("%s\n",B);
}

//*int dedouble { }
    
    
int main (void) {
	char B[20];
	devowel(B);
	printf("%s\n",B);
	return 0;
}
 
Last edited:
Dave,

Thanks for pointing out my newbish mistakes! And taking the time to explain why they are so. :D

I've modified the length of a [] to 27 characters (I didn't understand before that was how they were numberd) to prevent that fault. I've done a similar thing with the i variable by reducing the continuation parameter to i<=19.

I've also changed the scanf and printf to reflect the correct data to be read.

However, I'm still getting the same error. Any ideas?
 
Hey everyone,

I've taken in your comments and spent some more time researching. I've made a few changes and updated my op with the correct coding. I understand however there are a few fundamental flaws with the way I'm coding, but for now that's how I understand it.

You want the comparason operator '==' not '=', the asignment operator. But then you are assigning B=0; This will not remove the vowel, but terminate the string. So "test" will change to "t\0st" which is "t".


I'm still getting this problem though. I'll stick at it with a loop...

Thanks!
 
Hello again everyone,

Once more your comments have been extremely useful! However, I can go on with this dodgy way of coding no longer. Instead, I've spent a while taking in some of Caustic's and others comments to completely rewrite the code.

I've also taken the opportunity to add in the other bits of the code - removal of double letters, and the ignorance of first letters for both filters.

My code now looks something like:

Code:
#include <stdio.h>
#include <string.h>
#include <math.h>

void shift(int shifter, char* word, int len){
	int i;
	
	for (i = shifter; i != len ; i++)
		word[i] = word[i+1];
		
}

void capitalise(char* word, int len){
	int i;
	
	for (i = 0; i < len ; i++)
		if (islower(word[i]))
			word[i] = toupper(word[i]);
}

int devowel(char* word, int len){
	int i;
	
	for (i = 1; i <= len+1 ; i++)
		if (word[i] == 'A' ||
			word[i] == 'E' ||
			word[i] == 'I' ||
			word[i] == 'O' ||
			word[i] == 'U' ||
			word[i] == 'W' ||
			word[i] == 'Y' ||
			word[i] == 'H'){
				shift(i, word, len);
				len = strlen(word);
		}
	return len;
}

int dedouble(char* word, int len){
	int i;
	
	for (i = 0; i < len ; i++)
		if (word[i] == word[i+1])
		{
			shift(i+1, word, len);
			return 0;
		}
			
	return 1;
}

int main (void){
	char *word;
	int len;
	int flag = 0;
	
	scanf ("%s", word);
	len = strlen(word);
	capitalise(word, len);
	
	while (flag < 1){
		flag = dedouble(word, len);
		len = strlen(word);
	}
	
	len = devowel(word, len);
	len = devowel(word, len);
	printf("%s\n",word);
}

I think my tabulation is MUCH better here, which should help me keep track of what is doing what.

However I am still having slight problems - I can't seem to remove the last vowel off the end of strings when they are realllllly long. ie. eeeeffeeoooiiiee returns EFE. I'm not sure why this is. eeefffeeoooiiie returns the same. eeefffeeooiii returns the correct EF.

Any ideas why?

And a massive thank you to everyone so far, I would never have been able to improve this much without all your suggestions. OcUK never fails to amaze. :D

EDIT: forgot to mention - the code pasted is the one I'm trying to mess around with - hence the repeating of the devoweling.
 
"eeeeffeeoooiiiee" should become "f" according to your original post?

UPDATE1:

Spotted a nasty bug in devowel. You are doing a:

for (i = 1; i <= len+1 ; i++)

that means you are indexing past the end of the string. It should be

for (i = 1; i < len ; i++)

But why are you starting at 1?

I forgot to mention the first letter of the string should be preserved wether it is a vowel or not. Does that make more sense? :)
 
Back
Top Bottom