0

Been trying to remove the first element from a double pointer char array but i keep getting errors.

The input into the argv is from the keyboard using: argv is defined in main as

int main(int argc, char **argv)
    if(!fgets(*argv, 64, stdin))
        return 0;
    for (int i = 0; i < argc; i++)
    {
        j = 0;      
        while(j < strlen(*argv) - 1)
        {
            if(j == 0)
                strcpy(argv + j, argv + j + 1);
            j++;
        }
    }

Error:

warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
   22 |             {   if(j == 0) strcpy(argv + j, argv + j + 1);
      |                                             ~~~~~~~~~^~~
      |                                                      |
      |                                                      char **
8
  • 1
    Why are you reading a string into argv? You can read it into a locally defined char array. Commented Nov 12, 2022 at 14:18
  • What "errors" are you getting? Does your code not compile? Are you getting error messages from the compiler? Or is the run-time behavior of your program not what you want? Commented Nov 12, 2022 at 14:19
  • @ParhamAlvani: I have reverted your edit, because by fixing OP's code you may have destroyed evidence of what is wrong in OP's code. Commented Nov 12, 2022 at 14:20
  • @AndreasWenzel Thanks, I think the code has many issues besides of its compile issues. I just want to make it compile-able. Commented Nov 12, 2022 at 14:21
  • 1
    @ParhamAlvani: If OP is asking about why their code does not compile (which now seems to be the case), then it is not helpful for a third party to edit the code in the question to make it compilable. However, I don't blame you for doing this, because at the time, it was unclear what OP was asking about, and you were only trying to help. Commented Nov 12, 2022 at 14:30

1 Answer 1

1

Your code has many compile issues, first you need to define variable j and also using correct braces as follow:

#include <string.h>
#include <stdio.h>

int main(int argc, char **argv) {
    if(!fgets(*argv, 64, stdin))
        return 0;
    for (int i = 0; i < argc; i++)
    {
        int j = 0;
        while(j < strlen(*argv) - 1)
        {
            if(j == 0)
                strcpy(argv + j, argv + j + 1);
            j++;
        }
    }
}

After that, I am strongly against using argv for reading a string because you don't know anything about its size in memory. Also, when you are using the strcpy you must pay attention to the sizes, the destination string should have at least the size of the source.

strlen only works on strings which means char * so using it on char ** is meaningless. The following code copies each string into the left item which I think very similar to what you want to do but please note that string size is very important and strcpy can cause issue.

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

const int LEN = 255;

int main(int argc, char **argv) {
  int n = 3;

  // allocate memory for storing strings
  char **strings = malloc(n * sizeof(char *));

  // reading strings from user
  // and store them
  for (int i = 0; i < n; i++) {
    strings[i] = malloc(LEN * sizeof(char));

    // reads in at most one less than size characters from stream and stores them into the buffer pointed to by s
    fgets(strings[i], LEN, stdin);
  }

  for (int i = 0; i < n - 1; i++) {
    // here we consider all the strings has the max size as LEN
    // so this copy does not cause error.
    strcpy(strings[i], strings[i + 1]);
  }
  free(strings[n - 1]);

  for (int i = 0; i < n - 1; i++) {
    printf("[%d] %s", i, strings[i]);
  }
}

Also, you can use the non-dynamic way as follows:

#include <string.h>
#include <stdio.h>

#define LEN 255
#define N 3

int main(int argc, char **argv) {

  char strings[N][LEN];

  // reading strings from user
  // and store them
  for (int i = 0; i < N; i++) {
    // reads in at most one less than size characters from stream and stores them into the buffer pointed to by s
    fgets(strings[i], LEN, stdin);
  }

  for (int i = 0; i < N - 1; i++) {
    // here we consider all the strings has the max size as LEN
    // so this copy does not cause error.
    strcpy(strings[i], strings[i + 1]);
  }

  for (int i = 0; i < N - 1; i++) {
    printf("[%d] %s", i, strings[i]);
  }
}

Both programs have the following behavior:

Parham
Ali
Hassan
[0] Ali
[1] Hassan
Sign up to request clarification or add additional context in comments.

8 Comments

Why are you limiting the final loop to n - 1 iterations instead of n iterations? I understand why you are limiting the loop beforehand to n - 1 iterations, but I see no reason to limit the final loop to n - 1 iterations.
You don't free any of the memory you allocate with malloc.
Why are you using dynamic memory allocation (i.e. malloc) for allocating a memory for the strings. Dynamic memory allocation is slower and is more complicated, because it requires you to call free afterwards. Why not simply use a 2D array, like this: char strings[3][255];?
In the final loop I assume that we removed an string so I don't print the last string.
@ParhamAlvani: Ah, yes, you are right. OP stated that they want to "remove" the element, so it is appropriate to not print the entire array.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.