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

  1. #1
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95

    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. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    How does it not work?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    Quote Originally Posted by laserlight View Post
    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)
    it says: 3: command not found

    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. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    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
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    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.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    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
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    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. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You probably should use strcmp in this line:
    Code:
        while (argv[i] !=  sep) i++;
    And pass the string as "|".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    Quote Originally Posted by matsp View Post
    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. #10
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    Quote Originally Posted by matsp View Post
    You probably should use strcmp in this line:
    Code:
        while (argv[i] !=  sep) i++;
    And pass the string as "|".

    --
    Mats
    Did that but I get 3: command not found

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by simpatico_qa View Post
    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?
    Your hope is wrong

    Code:
    match(int A1[], int A2[])
    A1 and A2 are pointers to int, not arrays, so
    sizeof (A1) == sizeof(int*)
    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

  12. #12
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    So how can I pass array integers to the function?

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by simpatico_qa View Post
    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
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Mar 2009
    Location
    Bozen
    Posts
    95
    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. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
        static int * A1;
    Where does this point?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. create variable size arrays
    By s-men in forum C Programming
    Replies: 6
    Last Post: 08-27-2007, 07:45 PM
  2. 3 D arrays
    By helpCnewcomer in forum C Programming
    Replies: 1
    Last Post: 07-22-2005, 09:11 PM
  3. Arrays out-of-bounds in functions only?
    By KneeLess in forum C Programming
    Replies: 5
    Last Post: 11-03-2004, 06:46 PM
  4. If you are employed as a programmer, please look
    By Flood Fighter in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 09-28-2004, 02:35 AM
  5. Arrays failing to work
    By Bri Rock in forum C Programming
    Replies: 4
    Last Post: 06-14-2004, 06:34 PM