-1

Hi i was wondering why i can't manage to change the value of the variable "cinter" in this:

    int nbobject=7, cinter, i, *inter;

    printf("\nHow many elements in array :");
    scanf("%d", &cinter);
    inter=malloc(nbObject*sizeof(int));
    printf("\nEnter the elements :");
    for(i=0;i<cinter;i++){
       scanf("%d",&inter[i]);
    }
    qsort(inter, cinter, sizeof *inter, compare);
    noDuplicate(inter, cinter);
    cinter=noDuplicate(inter,cinter);
    for(i=0;i<cinter;i++){
        printf("%d", inter[i]);
    }
    printf("\nNumber of elements in array : ");
    printf("%d", cinter);
    printf("\nArray elements : ");
    for (i=0;i<cinter;i++){
       printf("%d ", inter[i]);
    }



   int noDuplicate( int arr[],int size ){
        int i=0, j=0;
        for (i = 1; i < size; i++){
           if (arr[i] != arr[j]){
              j++;
              arr[j] = arr[i]; // Move it to the front
           }
        }

        // The new array size..
        size = (j + 1);
        return size;

        }

So what i did is simply sort the array and remove the duplicate. I'd like for the variable "cinter" that's number of elements in the array to be reduced by the number of removed elements so that i can use it later on to know how many relevant elements are in the array but no matter what i always end up with the same number in the end.

Output :

How many elements in array : 6
Enter the elements : 2 1 2 3 5 1
Number of elements in array : 6
Array elements : 1 2 3 5 3 5

EDIT : @Arash here's a code you can run, all i need is to be able to change the value of cinter while i delete duplicates so i can use it later to know exactly how many relevant items are in my array.

    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>

    static int compare (void const *a, void const *b){
       int const *pa = a;
       int const *pb = b;
       return *pa - *pb;
    }

void main(){
    int  nbObjets=7, *inter;
    size_t cinter;
    size_t i, j;

    printf("\nHow many elements in the array :");
    scanf("%d", &cinter);
    inter=malloc(nbObjets*sizeof(int));
    printf("\nEnter the elements :");
    for(i=0;i<cinter;i++){
        scanf("%d",&inter[i]);
    }
    qsort(inter, cinter, sizeof *inter, compare);
    noDuplicate(inter, cinter);
    cinter=noDuplicate(inter, cinter);
    printf("\nNumber of elements in the array (cinter) : ");
    printf("%d", cinter);
    printf("\nArray elements : ");
    for (i=0;i<cinter;i++){
        printf("%d ", inter[i]);
    }
}


int noDuplicate( int arr[], size_t size ){
    size_t i=0, j=0;
    for (i = 1; i < size; i++){
        if (arr[i] != arr[j]){
            j++;
            arr[j] = arr[i]; // Move it to the front
        }
   }

   // The new array size..
    size = (j + 1);
    return size;
}

EDIT : I got it to work by making the changes that Arash told me to do, thanks for the help guys !

  • What does your compiler have to say about your code? – EOF Apr 21 '17 at 20:20
  • ...and where is the declaration for 'cinter'? What type is it? – ThingyWotsit Apr 21 '17 at 20:21
  • 2
    I am wondering why `inter=malloc(nbObject*sizeof(int));` ignores the value of `cinter` that you just entered, but then use in a loop to index `inter`. – Weather Vane Apr 21 '17 at 20:22
  • What is 'nbObject'? – ThingyWotsit Apr 21 '17 at 20:22
  • Ther is too much ??? and not enough MCVE ;( – ThingyWotsit Apr 21 '17 at 20:23
  • compiler doesn't have any issue with this part of the code ( i did initialize all the variables and everything is working fine ), my only problem is that no matter what i do, even if i write something like "cinter++;" or "cinter+=1" i can't change the value of cinter at all ... – Amine Chentouf Apr 21 '17 at 20:24
  • @ThingyWotsit Sorry i kind of just copied the relevant part of the code i needed help with and forgot about giving the type of each variable, it's edited now. – Amine Chentouf Apr 21 '17 at 20:27
  • 1
    If your compiler sees nothing wrong with `void noDuplicate( int arr[],size_t size ){[...] return size;}` you need to get a new one. – EOF Apr 21 '17 at 20:27
  • @WeatherVane nbObject is the number of all the object so it's the maximum value the array could hold so i allocated that in memory instead so i won't have to realloc later on, i will just need to delete duplicates so it doesn't exceed that number, and cinter is there just to tell me how many elements are actually in the array. – Amine Chentouf Apr 21 '17 at 20:29
  • @EOF Yes sorry, i had a bunch of warnings for other parts of the code that i still need to work on and didn't see the warning at the end saying that i had a void function returning a value, thanks for pointing that out, that is fixed now but i still can't get it to work regardless. – Amine Chentouf Apr 21 '17 at 20:33
  • 1
    Changing your post is not good SO etiquette. If needed, _append_ edits. Your post now makes obsolete some answers. Suggest reverting. – chux - Reinstate Monica Apr 21 '17 at 21:05
  • @chux my apologies, i'll keep that in mind for future edits, still learning how this all works, i always used to just look up questions similar to those i had and never really participated, i'll get the hang of it pretty soon. – Amine Chentouf Apr 21 '17 at 21:07
  • It is not shown the that `qsort()` works as intended. Printing the data after the sort and before `noDuplicate()` may help. – chux - Reinstate Monica Apr 21 '17 at 21:14
  • Using `size_t` for array size is best, yet `int` works OK for learner programs. But switching the type is not good. From `scanf()` to sort, noDupe(), and printing, use a consistent type. – chux - Reinstate Monica Apr 21 '17 at 21:16

2 Answers2

1

You can use pass by address to fix the problem:

void noDuplicate( int arr[],size_t *size ){
    size_t i=0, j=0;
    for (i = 1; i < *size; i++){
      if (arr[i] != arr[j]) {
        j++;
        arr[j] = arr[i]; // Move it to the front
      }
    }
    // The new array size..
    *size = (j + 1);
   } 

Then you call it this way:

 noDuplicate(inter, &cinter);
Arash
  • 1,950
  • 14
  • 17
  • Why using an indirection, when returning would do the deal? – Amin Negm-Awad Apr 21 '17 at 20:33
  • 2
    Because OP makes modification in the array itself as well. So I made both pass by address. – Arash Apr 21 '17 at 20:36
  • The first arg is a pointer, not an array. You cannot pass an array in C. Therefore it is never changed. Moreover, the pointer *is not* changed. However, this is no reason at all. For example you get problems by passing a literal for a predefined sized array. – Amin Negm-Awad Apr 21 '17 at 20:37
  • okay. it decays to a pointer. Editted. I think either way works: pass `cinter` by address or return the updated value. – Arash Apr 21 '17 at 20:48
  • The first arg *is* a pointer, because the *array* decays to a pointer. Using C you have to be exact. Again: Why adding a level of indirection, if a return value would do the deal? This has exactly *no* advantage and at least two disadvantages. – Amin Negm-Awad Apr 21 '17 at 20:51
  • Good question. Per [here](http://stackoverflow.com/questions/33994995/which-is-more-efficient-return-a-value-vs-pass-by-reference) your approach is more readable. – Arash Apr 21 '17 at 20:53
  • @Arash i tried it your way but my program crash when i call the noDuplicate function ... Compiler is giving me a : [Warning] conflicting types for 'noDuplicate' – Amine Chentouf Apr 21 '17 at 20:56
  • @Arash Of course, indirections always make things more complicated. – Amin Negm-Awad Apr 21 '17 at 20:57
  • @AmineChentouf Could you post a complete code that we can compile/run? – Arash Apr 21 '17 at 21:00
  • @Arash I just did, really thank you guys for the help ! – Amine Chentouf Apr 21 '17 at 21:18
  • @AminNegm-Awad BTW, I just saw the declarations in the first line of the post. I just assumed to be array..my bad. – Arash Apr 21 '17 at 21:19
  • @Arash it worked ! Using the last changed you've made i got it to work ! Thanks a bunch man ! :D – Amine Chentouf Apr 21 '17 at 21:21
  • @AmineChentouf Cool! You can [accept](http://stackoverflow.com/help/someone-answers) my answer if you find it useful. – Arash Apr 21 '17 at 21:27
0

You try to return the new size at the end in a void function. And the compiler doesn't complain? Make it int (and, btw, not size_t).

int noDuplicate( int arr[],size_t size )
{

(BTW: Throwing such an unformatted code in a Q is not very helpful.)

Of course in your main() you should assign the return value to cinter or whatever.

cinter = noDuplicate(inter, cinter);
Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
  • I changed the size_t to int, changed the void to int in the function as well, and also added the cinter= noDuplicate(inter, cinter); in the main all to no avail, cinter keep it's initial value ... Thank you for pointing some of my mistakes and sorry for the unformatted code i'm still new to the forum and don't really know how to use the tools correctly. – Amine Chentouf Apr 21 '17 at 20:53
  • I really do not understand your comment. Please add the new code to your Q. Does j+1 evaluate to the expected value? – Amin Negm-Awad Apr 21 '17 at 20:55
  • 1
    What value do you see in changing an array index type from `size_t` to `int`? – chux - Reinstate Monica Apr 21 '17 at 20:59
  • @AminNegm-Awad It's edited now, i've made the changes you requested and the result is actually the same as the original code ( when the function was still void with a return ... ) the value of `cinter` stays the same and trying to return a value to `cinter` in the main has no effect. – Amine Chentouf Apr 21 '17 at 21:05
  • You call the function twice. You do not want to do that. – Amin Negm-Awad Apr 23 '17 at 05:18