0

so I have a function that takes a Pointer to an array of 'Strings' (I understand strings as just blocks of memory that is followed by '\0'). Since a string is already a pointer to the first byte of a string, my pointer is actually a ** doublePointer. However I am seg-faulting off the Ying Yang and I honestly dont know what is going on in the low level view. Here is my code below, its function is to read characters and capitalize the first letter of the first word (in string) and after a period.

    void autocaps(char ** words)
    {

    /* Add code here */
    //Period Boolean
    bool next=false;
    //First Word Boolean
    bool fcap=true;
    //Counter Variable
    int i=0;
    int j=0;
    //Second Pointer
    char** wordx = words;

    //LowerCase Bomb & Period Flagging
    while(wordx[i][j]!='\0'){
      while(wordx[i][j]!='\0'){
       //A-Z Filter
       if((wordx[i][j]>='A')&&(wordx[i][j]<='Z')){
      wordx[i][j]+=32;
       }
       if(wordx[i][j]=='.'){
      next=true;
       }
      j++;
      }
    i++;
    }

 i=0;
 j=0;
 //Cap First Word & Cap Post Period
 while(words[i]!='\0'){
   while(words[i][j]!='\0'){
    //a-z Filter
    if((words[i][j]>=97)&&(words[i][j]<=122)){
  if(fcap){
    words[i][j]-=32;
    fcap=false;
  }
  if(next){
    words[i][j]-=32;
  }
    }
    j++;
  }
 i++;
}
return;

}

I am seg-faulting when I am printing the original pointer that was passed through the parameter. If someone could explain to me the low level concept of this because I am so confused I am throwing triple and quadruple stars in everywhere and I dont even know if it brings me closer or farther from debugging my code.

Thank You!!

Charles
  • 57
  • 5
  • Cannot say duplicate but [this](http://stackoverflow.com/questions/9460260/what-is-the-difference-between-char-a-string-and-char-p-string) should help. – Alok Save Feb 08 '13 at 07:22
  • `*wordx++` iterates over the strings, but you never iterate over the characters, so `**wordsx!='\0'` will only be false if you pass an empty string, which is probably not what you want. – Andreas Grapentin Feb 08 '13 at 08:11
  • 1
    All of this is based on whether you're actually passing a char ** into the function in the first place. Without the call-side of this invoke, it is undefined as far as answers to this question are concerned. Furthermore, you pass no length of your sequence. unless you use a tail-NULL pointer (which I see no evidence of) for your point-of-exit condition, this can go south in a hurry. Hint: If you're passing in a char[N][M] variable, you're doing it *wrong*. Please update the question to include a caller-side sample of how you're invoking this thing. – WhozCraig Feb 08 '13 at 08:26

2 Answers2

0

You said 'array of strings' but based on your code and your intent (capitalizing first character and after periods) I am going to make the assumption you intend this to work on the single string you pass to the function.

A string is just an array of characters followed by a 0 value. What you want to do is traverse the array of characters. To get from a character pointer to a character you want to dereference the pointer. That is why you see '*words' below everywhere we actually inspect the character we are at in the string.

Double, triple and quadruple pointers were taking you farther from the solution.

Here is a reworked sample:

void autocaps(char* words)
{
  bool fcap=true; /* true so first letter is made cap */

  while (*words != '\0') 
  {
    if (fcap)
    {
        /* capitalize */
        if ((*words >= 'a') && (*words <= 'z'))
        {
            *words -= 32;
        }

        fcap = false;
    }
    else
    {
        /* not cap */
        if ((*words >= 'A') && (*words <= 'Z'))
        {
            *words += 32;
        }
    }

    /* period - cap next letter */
    if (*words == '.')
    {
        fcap = true;
    }

    /* step to next character in array */
    words++;
  }

  return;
}
PQuinn
  • 992
  • 6
  • 11
  • Actually, I think he indeed intends to use an array of string pointers. But as @WhozCraig noted, we can not say for sure as long no caller code is provided. – Matthias Feb 08 '13 at 08:45
0

I you are initializing your array of strings as contant strings, something like:

char *words[2] = {"hello", "world"};

then you will get a segmentation fault the first time you get to

**words+=32;

because you are attempting to modify read-only location.

You should initializing the strings like so:

char word1[] = {'h', 'e', 'l', 'l', 'o', 0};
char word2[] = {'w', 'o', 'r', 'l', 'd', 0};
char *words[] = {word1, word2};

The other problem is indeed that of

*words++;

You do not want to do this for two reasons:

  1. as other posters mentioned, ++ has precedence over the dereferencing operator, and so you are actually incrementing the words array from one string to the next, and not one character to the next.
  2. the dereferencing operator then does not have any affect.

Now, if you want to advance to the next character you do not want to do this:

(*words)++

because now you are actually changing the pointer in the words array, and you do not want to do that.

c-is-best
  • 146
  • 2
  • 9
  • hi guys, thank you so much for your responses and sorry if I confused you or did not make it clear what I was doing. I edited my code to be more accurate to what I am trying to accomplish. So autocaps is being called on rolodex which is initialized as char* rolodex[25]={NULL}; which is initialized by another function. autocaps(rolodex); this is therefore a 2 dimensional array as it is an array of pointers to strings. – Charles Feb 09 '13 at 04:02