Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5

Thread: C input problem

  1. #1
    Regular Coder brad211987's Avatar
    Join Date
    Sep 2005
    Location
    Ohio
    Posts
    631
    Thanks
    10
    Thanked 50 Times in 50 Posts

    C input problem

    I'm doing a C program for a class assignment, and have run into a problem. The program creates a custom shell and lets you run normal unix commands from it. The problem I have run into is handling the optional arguments. My question is, how would you take input in C that has a variable number of optional arguments. For example, one command could be 'ls' where another could be 'ls -l' etc....

    Using scanf I'm not sure if it's possible because you specify the arguments in the format string. I tried using getline but it simply froze the program and I had to force it to end the process.

    Is getline the way to go here or is there a better way to accept all of the input? If I could get the entire input string I could parse it myself.

  • #2
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    Which compiler are you using? getline isn't standard C so its behavior is implementation defined. That said, assuming you and your prof are using the same compiler it's much preferable to gets and fgets.

    Here's how it works for GCC (note it even requires a GNU-specific definition, lest there be any misconception about its portability):

    Code:
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main()
    {
    	size_t LINE_LEN = 1024;
    	char* line = malloc(LINE_LEN);
    
    	getline(&line, &LINE_LEN, stdin);
    	printf("%s", line);
    
    	free(line);
    	return 0;
    }
    Which just echos back the first input line. (NB: I'm not a C programmer, that code may not be 100% trustworthy, but it seems to work)

    I know you're good on the parsing end of it, but just as a quick note strtok() is probably very useful here in addition to scanf().

  • Users who have thanked ralph l mayo for this post:

    brad211987 (09-10-2007)

  • #3
    Regular Coder brad211987's Avatar
    Join Date
    Sep 2005
    Location
    Ohio
    Posts
    631
    Thanks
    10
    Thanked 50 Times in 50 Posts
    Thank you for the response, the compiler used is GCC so this shouldn't be a problem. I will try this when I get home tonight. Will post back the results. Thanks again!

  • #4
    Regular Coder brad211987's Avatar
    Join Date
    Sep 2005
    Location
    Ohio
    Posts
    631
    Thanks
    10
    Thanked 50 Times in 50 Posts
    that worked great! thanks for the help. But im back again with another problem.

    At this point, I have the input, and have parsed it inside of a while loop so im getting one argument at a time. I need to place each one of these into an array that can be passed to the execve unix command. Here is an example I was looking at to figure this out:

    Code:
    char *const parmList[] = {"dir", "/L", "/", NULL};
    char *const envParms[1] = { NULL};
    
    execve("dir", parmList, envParms);
    In that code, the parmList is hard coded, I'm attempting to build this with the parameters I read from stdin using the getline. My problem is, that I don't know the size of the array until I read the line. Any idea how to take one string at a time and place it into an array?

  • #5
    Regular Coder ralph l mayo's Avatar
    Join Date
    Nov 2005
    Posts
    951
    Thanks
    1
    Thanked 31 Times in 29 Posts
    You have to use dynamic memory allocation for anything you can't tell the size of at compile time unless you're lucky enough to be using C++ in which case you can let a container do the work for you.

    Code:
    /* Take a wild guess at how many characters you'll need per parameter, including one for the null terminator */
    size_t param_len = 10;
    size_t params = 0;
    /* ... Some stuff to parse the line goes here, which also increments params for each to arrive at the actual # passed ... */
    
    char** paramList = malloc(param_len*params);
    /* ... work with array, execve or whatever ... */
    free(paramList);
    *no warranty, mind the overflow vulnerability somehow


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •