# Thread: Create two arrays from command line and work on them

1. ## Create two arrays from command line and work on them

Hello,
I'm trying to make it possible such that when I run from the commadn line the following :
./program 1 2 3 | 3 4 5
it will create two arrays, A and A1 and process them as per the match function (which I did test to work). So I only need help with the Array extractor methods and the main. Awaiting your kind suggestions.

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void match(int A1[], int A2[]){
int n1 = sizeof(A1);
int n2 = sizeof(A2);
int i,m,a1k,a2i,l,r,a1m;//global variables
int a10=A1[0];

for (i=0; i<n2; i++){//scan all elements of A2
a2i = A2[i];//for efficiency
if (a10 == a2i || A1[i]==a2i) printf("%d\t",a10);//special cases: print element
else{ //when special case not true
r = n1-1;
l = 0;
if (a2i >= a1k){
if (a1k == a2i)
printf("%d\t",a1k); //print the element
else{
while(r>=l){//since A1 is sorted
m = (l+r)/2;
if (a2i == (a1m = A1[m])){ //if element is found
printf("%d\t",a1m); //print the element
break;}
else{
if (a1m > a2i) r = m-1;
else l = m+1;
}
}
}
}
}
}
}
int * arrayExtractor(const char * argv[], char sep[]){
int n,i=1;
while (strcmp(argv[i], sep) != 0) {n++;}
static int * A;
for (i=1; i<n; i++){A[i] = atoi(argv[i]);}
return A;
}
int * arrayExtractor2(const char * argv[], char sep[]){
int i=2;
while (argv[i] !=  sep) i++;
static int * A1;
for (i=2; argv[i] != '\0'; i++){A1[i] = atoi(argv[i]);}
return A1;
}
int main(int argc, const char * argv[]){
match (arrayExtractor(argv, '|'), arrayExtractor2(argv,'|'));
return 0;
}```

2. How does it not work?

3. Originally Posted by laserlight
How does it not work?
If you try to run it from the command line it gives:
When compiling it says:
in function ‘main’:
....c:57: warning: passing argument 2 of ‘arrayExtractor’ makes pointer from integer without a cast
.....c:57: warning: passing argument 2 of ‘arrayExtractor2’ makes pointer from integer without a cast
When executing (given 1 2 3 | 3 4 5)

BTW: I noticed the match method also had some error, so the code should be:

Code:
```void match(int A1[], int A2[]){
int n1 = sizeof(A1);
int n2 = sizeof(A2);
int i,m,a1k,a2i,l,r,a1m;//global variables
int a10=A1[0];

for (i=0; i<n2; i++){//scan all elements of A2
a2i = A2[i];//for efficiency
a1k = A1[i];
if (a10 == a2i || a1k==a2i) printf("%d\t",a2i);//special cases
else{ //when special case not true
r = n2-1;
l = 0;
if (a2i >= a1k){
while(r>=l){//since A1 is sorted
m = (l+r)/2;
if (a2i == (a1m = A1[m])){ //if element is found
printf("%d\t",a1m); //print the element
break;
} else{
if (a1m > a2i) r = m-1;
else l = m+1;
}
}
}
}
}
}
int * arrayExtractor(const char * argv[], char sep[]){
int n,i=1;
while (strcmp(argv[i], sep) != 0) {n++;}
static int * A;
for (i=1; i<n; i++){A[i] = atoi(argv[i]);}
return A;
}
int * arrayExtractor2(const char * argv[], char sep[]){
int i=2;
while (argv[i] !=  sep) i++;
static int * A1;
for (i=2; argv[i] != '\0'; i++){A1[i] = atoi(argv[i]);}
return A1;
}
int main(int argc, const char * argv[]){
match (arrayExtractor(argv, '|'), arrayExtractor2(argv,'|'));
return 0;
}```

4. It's not in your app, that is the shell (command prompt) that tries to feed your second set of commands as a second application with arguemnts.

Using the correct type of quoting or escaping would help. How you do that depends on the environment you are running your code in. Or pick a different separator (something the shell doesn't interpret - perhaps / would work).

The warnings you get is becuase you are passing '|' to the splitter function, when you actually should be using "|" to make it a string (rather than a single character).

--
Mats

5. You could also use quotes, eg.
./program "1 2 3" "4 5 6"
This will give you two arguments
Code:
```argv[1]="1 2 3";
argv[2]="4 5 6";```
which you could parse with sscanf or something.

6. Code:
```    int n1 = sizeof(A1);
int n2 = sizeof(A2);```
Pre-emptive strike: This will not work - you will have both n1 and n2 exactly identical values, no matter how many or how long your strings are. You will want to use strlen() or some other similar function to determine the LENGTH of A1 and A2.

--
Mats

7. matsp, it would be much more useful if you directly add your suggestions to the code. I was using "|" before it didn't work either (and was using the string compare funct).
Could you please show me how on a unix system (or windows) the code would work?

8. You probably should use strcmp in this line:
Code:
`    while (argv[i] !=  sep) i++;`
And pass the string as "|".

--
Mats

9. Originally Posted by matsp
Code:
```    int n1 = sizeof(A1);
int n2 = sizeof(A2);```
Pre-emptive strike: This will not work - you will have both n1 and n2 exactly identical values, no matter how many or how long your strings are. You will want to use strlen() or some other similar function to determine the LENGTH of A1 and A2.

--
Mats
I don't get what you say. Both A1 and A2 are supposed to be identical size int arrays, but with different values. Where is the problem?

10. Originally Posted by matsp
You probably should use strcmp in this line:
Code:
`    while (argv[i] !=  sep) i++;`
And pass the string as "|".

--
Mats

11. Originally Posted by simpatico_qa
I don't get what you say. Both A1 and A2 are supposed to be identical size int arrays, but with different values. Where is the problem?

Code:
`match(int A1[], int A2[])`
A1 and A2 are pointers to int, not arrays, so
sizeof (A1) == sizeof(int*)

12. So how can I pass array integers to the function?

13. Originally Posted by simpatico_qa
So how can I pass array integers to the function?
Like you do, but you ALSO need to tell the function what size(s) the arrays are.

sizeof() is a static size - which means that the compiler doesn't generate code to somehow find out what the size of a variable is at runtime, it figures out what size it is at compile time. Since the compiler doesn't know what you pass into the function (and even if it can see what is being passed in at a particular point, it doesn't KNOW that you won't call the function from some other bit of code that it doesn't currently know about - and in this case, it doesn't know what is passed on the command-line).

My post at 12:13 (about an hour ago from this post) explains why you get "3 command not found", but I will try to be more clear, as you seem to not have got the message:
You are using | which is a "pipe" in most shells - it means "Send the output of the program to this program", so when you say:
Code:
`./program 1 2 3 | 3 4 5`
then the shell will interpret that as:
Code:
```./program 1 2 3
(create a pipe and connect the output of the ./program to the input of this)
3 4 5```
Since you do not have a program called 3, it says "3: Command not found" - it can not find a program/command called 3!

I did suggest that you find a better character than | to separate your inputs. "/" may be better, as it is generally unchanged when passed as an argument. Certainly
Code:
`"(){}[]^*%\$~!"`
are no good because they are being "used". "_", "=", "+" or "-" are also possibles, but at least "-" may cause trouble because it is also the minus-sign. You could of course also use some general letter, e.g. "a" or "X".

--
Mats

14. I made what looks like the required changes, but now I get a bus error.
Code:
```void match(int A1[], int n1, int A2[], int n2){
int i,m,a1k,a2i,l,r,a1m;//global variables
int a10=A1[0];

for (i=0; i<n2; i++){//scan all elements of A2
a2i = A2[i];//for efficiency
a1k = A1[i];
if (a10 == a2i || a1k==a2i || A1[n1-1] == a2i) printf("%d\t",a2i);//special cases
else{ //when special case not true
r = n2-1;
l = 0;
if (a2i > a1k){
while(r>=l){//since A1 is sorted
m = (l+r)/2;
if (a2i == (a1m = A1[m])){ //if element is found
printf("%d\t",a1m); //print the element
break;
} else{
if (a1m > a2i) r = m-1;
else l = m+1;
}
}
}
}
}
}
int * arrayExtractor(const char * argv[], char sep[]){
int n,i=1;
while (strcmp(argv[i], sep) != 0){n++;}
static int * A;
for (i=1; i<n; i++){A[i] = atoi(argv[i]);}
return A;
}
int * arrayExtractor2(const char * argv[], char sep[]){
int i=2;
while (strcmp(argv[i], sep) != 0) {i++;}
static int * A1;
for (i=2; argv[i] != '\0'; i++){A1[i] = atoi(argv[i]);}
return A1;
}
int main(int argc, const char * argv[]){
match (arrayExtractor(argv, "/"), sizeof(arrayExtractor(argv, "/")), arrayExtractor2(argv,"/"),sizeof(arrayExtractor2(argv,"/")));
return 0;
}```

15. Code:
`    static int * A1;`
Where does this point?

--
Mats