Thread: Issue with pointer math

  1. #1
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92

    Issue with pointer math

    Hello all.

    I am trying to learn C and have a PHP background.

    What I am looking to do (to learn C some more) is to read a file line by line and return what items in the list are missing.

    Example lines are:

    Store 1
    Store 2
    Store 3
    Store 12
    Store 13
    Store 19
    Store 20

    I would like to have the application return a list such as

    Store 4
    Store 5
    Store 6
    ...
    Store 14
    Store 15
    ...

    Here is what I have thus far and it currently thinks "next" in "*getMissingStores" is 123456789. This program was looking a lot better as far as structure is concerned, but I have been just trying to get it to work so it may look a bit jumbled.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define STORE_FILE "c:/stores.txt"
    
    char *strip_newline(char *szString){
      if(szString[strlen(szString)-1] == '\n')
        szString[strlen(szString)-1] = '\0';
      return szString;
    }
    
    int getDigits(char *szString){
      char *tmp = strchr(szString, ' ');
      char *tmp2;
      if(tmp == NULL) return -1;
      tmp++;
      if(tmp != NULL){
        tmp2 = tmp;
        tmp2[strlen(tmp2)+1] = '\0';
        return atoi(tmp2);
      } else {
        return -1;
      }
    }
    
    char *getMissingStores(char *szStoreNums){
      int next = getDigits(szStoreNums + 1);
      int curr = getDigits(szStoreNums);
      do {
        while(curr != next && curr < next){
          printf("Store &#37;d is missing.\n", ++curr);
          printf("Curr: %d -> Next: %d", curr, next);
        }
        next = atoi(++szStoreNums);
      } while(szStoreNums != NULL);
      return;
    }
    
    int main(int argc, char **argv){
      
      FILE *storeFile = fopen(STORE_FILE, "r");
      /** create space for the store names **/
      char storeList[200][51];
      
      if(storeFile == 0){
        printf("Could not open file %s for reading.\n", STORE_FILE);
        system("pause");
        return -1;
      } else {
        /** begin to read the file **/
        int i = 0;
        while(fgets(storeList[i], 1024, storeFile) != 0){
          strip_newline(storeList[i]);
          printf("Read in: %s\n", storeList[i]);
          printf("Digits are: %d\n\n", getDigits(storeList[i]));
          i++;
        }
        char *szMissingStores = getMissingStores((char *)storeList);
        printf("Total stores on file: %d\n", i);
      }
      
      system("pause");
      
      return 0;
    }
    Any pointers would be appreciated and I am not against recoding the entire thing.
    Last edited by Kudose; 03-17-2008 at 10:48 PM.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,794
    fgets(storeList[i], 1024, storeFile)

    do not lie to fgets - you r buffer is only 50 bytes long asking to write there 1024 byte - it is asking for crash

    getMissingStores((char *)storeList);
    do not lie to getMissingStores - your 2D array has another type

    getMissingStores should be rewritten in full

    tmp2[strlen(tmp2)+1] = '\0'; - what do you want to achieve here? strlen already has found last not-nul char - so next char is '\0', why do you need to overwrite with nul one more char?
    Why do you need tmp2 at all?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    David J. Wheeler

  3. #3
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    Thanks for your comments. Here is what I've come up with. Unfortuantely I get a invalid pointer type error when calling printStoreList

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define STORE_FILE "c:/stores.txt"
    
    char *strip_newline(char *szString){
      if(szString[strlen(szString)-1] == '\n')
        szString[strlen(szString)-1] = '\0';
      return szString;
    }
    
    int getDigits(char *szString){
      char *tmp = strchr(szString, ' ');
      char *tmp2;
      if(tmp == NULL) return -1;
      tmp++;
      if(tmp != NULL){
        tmp2 = tmp;
        tmp2[strlen(tmp2)+1] = '\0';
        return atoi(tmp2);
      } else {
        return -1;
      }
    }
    
    void printMissingStores(char **szStoreNums){
      int next = getDigits(*(szStoreNums + 1));
      int curr = getDigits(*(szStoreNums));
      do {
        while(curr != next && curr < next){
          printf("Store &#37;d is missing.\n", curr);
          printf("Curr: %d -> Next: %d", curr, next);
          curr++;
        }
        next = atoi(++(*szStoreNums));
      } while(szStoreNums != NULL);
      return;
    }
    
    int main(int argc, char **argv){
    
      FILE *storeFile = fopen(STORE_FILE, "r");
      /** create space for the store names **/
      char storeList[200][51];
    
      if(storeFile == 0){
        printf("Could not open file %s for reading.\n", STORE_FILE);
        system("pause");
        return -1;
      } else {
        /** begin to read the file **/
        int i = 0;
        while(fgets(storeList[i], 50, storeFile) != 0){
          strip_newline(storeList[i]);
          printf("Read in: %s\n", storeList[i]);
          printf("Digits are: %d\n\n", getDigits(storeList[i]));
          i++;
        }
        printMissingStores(storeList);
        printf("Total stores on file: %d\n", i);
      }
    
      system("pause");
    
      return 0;
    }
    Can you explain or provide a good link to why you can't have function(char arr[][])?

    Is char[][] equal to char**? If not, why?

    How can I ditch arrays and use pointers only?

    This might be overkill, but would a linked list using structs be better than arrays?

    Thanks for your insights.
    Last edited by Kudose; 03-18-2008 at 02:27 AM.

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,794
    Is char[][] equal to char**? If not, why
    It is not

    when you make ptr++; it is advanced on sizeof(*ptr) bytes

    because sizeof (char*) is 4 bytes it will not advance the whole "row" and you get the wrong location

    Make function prototype like
    Code:
    void printMissingStores(char szStoreNums[][51], size_t rowNumber);
    in this case szStoreNums[i] will be advanced full i rows and be pointing the right point n the 2D array
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    David J. Wheeler

  5. #5
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    Thanks for your assistance.

    I got it up and running with this function

    Code:
    void printMissingStores(char szStoreNums[][STORE_NAME_MAX_SIZE+1]){
      int sizeA = sizeof(szStoreNums);
      int sizeB = sizeof(szStoreNums[0]);
      int total = sizeB/sizeA;
      printf("Incomplete stores:\n");
      int i;
      int incomplete = 0;
      for(i = 0; i < total; i++){
        int y = getDigits(szStoreNums[i]);
        int z = getDigits(szStoreNums[i+1]);
        while(y < z && (y+1 != z)){
          printf("Store &#37;d\n", ++y);
          incomplete++;
        }
      }
      printf("\nIncomplete stores: %d\n", incomplete);
      return;
    }
    Mainly because I wan't sure what to do with size_t rowNumber :\

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,794
    I got it up and running with this function
    And what is your total value? It does nothing to do with the array size.

    Mainly because I wan't sure what to do with size_t rowNumber
    It should be number of rows in the array you have initialized.
    And your loop should look like
    Code:
    for(i = 0; i < rowNumber ; i++){
    Also note that due to [i+1] access inside the loop - it should be actually
    Code:
    for(i = 0; i < rowNumber-1 ; i++){
    to avoid out of bounds access
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    David J. Wheeler

  7. #7
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    A quick fix of your print routine, works finely if you pass your 'i' == total stores read as a 2nd parameter.
    Code:
    void printMissingStores(char szStoreNums[][51], int sz)
    {
        int idx = 0;
        int prev;
        int curr;
        do {
            prev = getDigits(szStoreNums[idx]);
            curr = getDigits(szStoreNums[idx + 1]);
            if (curr > prev + 1) {
                for (prev = prev + 1; prev != curr && prev < curr; prev++) {
                    printf("Store &#37;d is missing.\n", prev);
                    printf("Prev: %d -> Curr: %d\n", prev, curr);
                }
            }
            idx++;
            while (idx < sz && getDigits(szStoreNums[idx]) < prev)
                idx++;
        }
        while (idx < sz - 1);
        return;
    }
    Last edited by xuftugulus; 03-18-2008 at 04:29 AM.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  2. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  3. sorting with pointer of pointers to array
    By dunpealslyr in forum C++ Programming
    Replies: 6
    Last Post: 10-01-2007, 11:26 PM
  4. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  5. Another Linked List plee
    By Dragoncaster131 in forum C Programming
    Replies: 3
    Last Post: 05-15-2004, 05:40 PM