-2

Hy everybody, I really can't figure out why this code I wrote is not working. I need to store in an array the integers passed through the command line after the name of a file to open. The code is the following:

void read(int **a, int argc, char *argv[]) {
    int i;
    char temp[20];

    if((*a = malloc(sizeof(int) * (argc - 2))) == NULL){
        fprintf(stderr, "Error.\n");
        exit(-1);
    }

    for (i = 2; i < argc; i++){
        strcpy(temp, argv[i]);
        **(a + i - 2) = atoi(temp);
    }
}

Can anybody help please? Thanks a lot!

Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
  • you got so many issue, and one of them show me that you should read some documentation about C before try to code in C... function argument are local to the function for example. – Stargateur Apr 16 '18 at 18:31
  • Of course they are, but this function was supposed to be invoked with the arguments within the main function, so that's just a label for formal parameters! Maybe it's not the best practice but it's easier to remember what should I pass to the subroutine. – Antonino DG Apr 16 '18 at 18:35
  • 1. No need tor `temp` variable here. 2. Filling in your array is easy, just `(*a)[i-2] = atoi(argv[i]);`. – Steve Summit Apr 16 '18 at 18:37
  • "code I wrote is not working" is vague. Post explicit explanation of "not working" including the values of `argc, argv[]`, what you saw and was was expected. – chux - Reinstate Monica Apr 16 '18 at 18:46
  • `argc-2` ... ?! don't you mean `argc+2`? ... I mean, what if `argc == 1`...? You will get `-1`, but `malloc` is unsigned, which meant you will get `SIZE_MAX`... a very Big `malloc` value. – Myst Apr 16 '18 at 18:53
  • @chux, it's not storing the values properly! myst No because as I explained there is a File to open whose name is passed through the command line and if it would not be the case the program would terminate since I already parsed the command line. – Antonino DG Apr 16 '18 at 18:57
  • 1
    @AntoninoDG The posted code does not demonstrate "it's not storing the values properly". Neither have you posted the input, incorrect output seen, nor the expected result. Without more information, the post is insufficient. – chux - Reinstate Monica Apr 16 '18 at 19:25
  • always check `argc` before manipulating the value contained in `argc` – user3629249 Apr 17 '18 at 05:51
  • @AntoninoDG, did the answer below solve your problem? You just needed the `*(*a + i + 2)`, right? – tbrk Apr 19 '18 at 05:19
  • @tbrk Yes it helped, I just messed around with referencing. Thanks!! – Antonino DG Apr 19 '18 at 12:48

1 Answers1

2

You could try dropping the temporary string variable and using array index notation for the array access.

void read(int **a, int argc, char *argv[])
{
    int i;

    if (argc < 3) {
        *a = NULL;
        return;
    }

    if ((*a = malloc(sizeof(int) * (argc-2))) == NULL){
        fprintf(stderr, "Error.\n");
        exit(-1);
    }

    for(i=2; i < argc; i++){
        (*a)[i - 2] = atoi(argv[i]);
    }
}

Otherwise, the array access should be *((*a)+i-2); i.e., dereference the double pointer to get an array pointer, apply pointer arithmetic to find the right element, and then dereference it.

A more generic version of this function would be:

int *map_atoi(int n, char * strs[])
{
    int i, *r;

    if (n < 1) return NULL;

    r = calloc(n, sizeof(int));

    if (r != NULL) {
        for(i=0; i < n; i++) {
            r[i] = atoi(strs[i]);
        }
    }

    return r;
}

It could be called from main as a = map_atoi(argc - 2, argv + 2). The parsing of strings into integers is then isolated from the particularities of the command-line processing, giving a more cleanly specified and reusable unit.

tbrk
  • 1,290
  • 1
  • 13
  • 20
  • `argc-2` - what if `argc == 0`? – Myst Apr 16 '18 at 18:51
  • I agree. I didn't add it because the original spec is so specific. But you're right. I'll edit it in. – tbrk Apr 16 '18 at 18:55
  • argc is at least equal to one, since argv[0] stores the name of the program. Moreover As I explained those numbers came after a string – Antonino DG Apr 16 '18 at 18:59
  • 1
    @AntoninoDG [`argc` can be zero](https://stackoverflow.com/questions/49817316/can-argc-be-zero-on-a-posix-system). – dbush Apr 16 '18 at 19:07