#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    10
    Rep Power
    0

    How to pass/return parameters in C


    Hi All,

    I am a C# guy, have been for the last 8 yrs.
    C is a real pain in comaprision, but I digress.

    My issue is in trying to make a simple program to accept parameters and return the concatonated parameters. A simple concept but OMG what a challenge in C. Help would be greatly appreciated.

    Here is my current code:

    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    char main(char *a, char *b)
    {
       a = "test";
       b = "Hello";
    
       printf("%s\n", a);
       printf("%s\n", b);
    
       strcat(a, b);
       printf("Concatonated strings are %s\n", a);
     
       system("pause");
       return *a;
    }
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    156
    Rep Power
    33
    In C, the function main() returns an int (except in implementations that defy the Standard). The function main() either takes no parameters or takes 2 parameters (except in implementations that defy the Standard): the first one of type int and the second one of type char **. The names of the parameters are up to the programmer, but nearly everyone always uses argc and argv.

    Code:
    int main(void) { /* ... */ }
    Code:
    int main(int argc, char **argv) { /* ... */ }
    Code:
    int main(int argc, char *argv[]) { /* ... */ }
    The parameters supply information to the program about any command line arguments passed in: argc is a count of the arguments, and argv elements are those arguments.
    Changing the values of the variables, while allowed, is very bad form (and may even crash the program in some situations).

    What you want to do is allocate space for the concatenad result, and loop until all command line arguments are exhausted

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char **argv) {
        char *result = NULL;
        size_t rsize = 1; /* remember to count the NUL string terminator */
        int current = 1; /* NOTE: argv[0] is the program name, if available */
        while (current < argc) {
            char *tmp = realloc(result, rsize + strlen(argv[current]));
            if (!tmp) {
                fprintf(stderr, "Not enough memory. Program aborted.\n");
                exit(EXIT_FAILURE);
            }
            result = tmp;
            rsize += strlen(argv[current]);
            strcat(result, argv[current]);
            current++;
        }
        printf("all concatenated: %s\n", result);
        free(result);
        return 0;
    }
  4. #3
  5. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,607
    Rep Power
    4247
    You've got several mistakes in your code. Here's a better version:
    Code:
    #include <stdio.h>
    
    int concat_strings(char *str1, char *str2, char *output, int *size);
    
    int main(void) {
        char *a = "test";
        char *b = "Hello";
        char output_buffer[100];
        int buf_size = sizeof(output_buffer);
    
        if (concat_strings(a, b, output_buffer, &buf_size)) {
            printf("Output buffer is: %s\n", output_buffer);
        }
        else {
            printf("Output buf is too small. Need at least %d bytes\n", buf_size);
        }
    
        return 0;
    }
    
    int
    concat_strings(char *str1, char *str2, char *output, int *buf_size) {
        int max_size = *buf_size;
        int result_size = snprintf(output, max_size, "%s%s", str1, str2);
        *buf_size = result_size + 1;
        if (result_size >= max_size) {
            // Buffer is too small to hold contents
            return 0;
        }
    
        return 1;
    }
    concat_strings() not only concatenates the strings, it also does a couple of other useful things:
    1. It returns the actual # of bytes used after the strings are concatenated.
    2. It returns whether it successfully managed to concatenate the strings or not.
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    10
    Rep Power
    0
    bdb, your code just displays: all concatenated <null>.

    Scorpions, yours always says the buffer is to small regsardless of how big I make it.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    156
    Rep Power
    33
    Originally Posted by TheDeadveloper
    bdb, your code just displays: all concatenated <null>.
    Try calling the program with a few command line arguments :)

    But, I agree the program should check for at least one parameter.
    Add the following line right after "int current = 1;"
    Code:
    if (argc == 1) { fprintf(stderr, "Use arguments, please.\n"); exit(EXIT_FAILURE); }
    Last edited by bdb; October 10th, 2012 at 03:36 PM.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    10
    Rep Power
    0
    Ok, well what if I wanted to call this from an AS400 application and send in parameters and get something back?

    What about not having a Main and just a function with a pragma map to it? Example below.

    Code:
    #pragma map (hello(char), "HELLO")
    char hello(char a)
    {
    printf(a);
    strcpy(a, "Hello");
    printf(a);
    return a;
    }
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    156
    Rep Power
    33
    I don't know about compiling C on the AS/400 (or about the non-standard pragmas) ... but the code I posted is plain old regular Standard C89.

    If the AS/400 can run a program with parameters (CALL PGM(LIBRARY/OBJECT) PARM(ONE TWO THREE) maybe), I'm very much convinced my program above works flawlessly.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    10
    Rep Power
    0
    I just got more information on what it is we are really trying to do.

    On the AS400 there will be an RPG app that will call a C wrapper for a web service call. The web service will return a string to the c wrapper, which will then hand it off to the RPG app.

    So as a .NET guy this seems like alot of stuff for such a simple task, but what can I do.

    Looks like I need a pragma map to a function; i.e. NO main.

    Then I should be able to send in and get back parameters correct?
  16. #9
  17. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,607
    Rep Power
    4247
    Originally Posted by TheDeadveloper
    Scorpions, yours always says the buffer is to small regsardless of how big I make it.
    What did you change in the code? The example I posted above should concatenate the two strings correctly.
    Code:
    mb@motorhead:~/cpp$ ./testfoo 
    Output buffer is: testHello
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    156
    Rep Power
    33
    Originally Posted by Scorpions4ever
    ... The example I posted above should concatenate the two strings correctly.
    Note that your example relies on C99's snprintf().
    If the OP is using a C89 compiler that accepts snprintf() as an extension it's anybody's guess what his snprintf() accepts and returns (I couldn't find any relevant information on the AS400 compiler and the Windows library is not C99 compatible).
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    10
    Rep Power
    0
    So what we have to do is use the pragma map to get access to a function that will pass the parameters and return one.

    Something like this:
    Code:
    #include <stdio.h>
    #include <string.h>
     
    #pragma map (hello(char[]), "HELLO")
    char* hello(char *a[])
    {
    	printf(*a);
    	strcpy(*a, "Hello");
    	printf(*a);
    	return *a;
    }
  22. #12
  23. No Profile Picture
    I haz teh codez!
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Dec 2003
    Posts
    2,548
    Rep Power
    2337
    Been doing this **** for 15+ years, and have never seen this #pragma map in use. Above my pay grade perhaps.

    This page might be useful?
    I ♥ ManiacDan & requinix

    This is a sig, and not necessarily a comment on the OP:
    Please don't be a help vampire!
  24. #13
  25. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    10
    Rep Power
    0
    It is an example we received from another company.

    Here is the explanation.

    Honestly, I have no freakin clue.
    Like I said earlier I'm a C# guy.

    I can see that the industry needed this stuff at one point in time but I am thankfull we have moved ahead.
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    10
    Rep Power
    0
    Here is the actual implementation we are trying to achieve.

    I have no idea how to get this to work in a C project.

    With .NET I can just discover the service and it writes all the references for me.

    The C++ project in Visual Studio 2010 does not seem to have a way to add a web service. Grr...

IMN logo majestic logo threadwatch logo seochat tools logo