LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 10-30-2012, 07:16 AM   #1
micflunu
Member
 
Registered: Oct 2012
Posts: 73

Rep: Reputation: Disabled
How to parse commandline arguments in C


I am tring to write my own c shell and i am having a hard time parsing variable number of arguments.I want a simple parsing function.Now i am confused and don even know how to start.cld any one help me??my system is ubuntu.

Last edited by micflunu; 10-30-2012 at 11:13 AM.
 
Old 10-30-2012, 07:08 PM   #2
Heraton
Member
 
Registered: Apr 2011
Location: Germany
Distribution: Mint 10, openSuSE
Posts: 58

Rep: Reputation: 3
Smile This might be the droids you are looking for...

Hello micflunu!

I am not sure what you want to be helped with exactly, but I am willing to try and guess. If your problem is with parsing the arguments, then getopt is the function to know. While you are on your linux box, try
Code:
man 3 getopt
This should get you started with probably the most important function for parsing command line arguments.

If you do not even know where to start, then you might be better of to get some basic understanding of c before you try to write your own shell. Anyway, here is a simple c program that does some demonstration on how to access the command line arguments of a program (tested, but no warranty anyway):
Code:
#include <stdio.h>

int main( int argc, char * argv[] )
{
	printf("Number of arguments was %d\n",argc - 1);
	int i;
	for( i=0; i<argc; i++)
	{
		printf("Argument No. %d was: \"%s\"\n",i,argv[i]);
	};
}
Don't get me wrong, but I can not tell from your post about your programming expertise, and therefore assume little knowledge so I am most likely to be understood.

Maybe you should try to be more descriptive with your next post, so the help can be more precise. Using the programming subforum might have been a better choice too. And, by the way, cld you stop txt spk? It is not very popular around here...

Regards, Heraton
 
1 members found this post helpful.
Old 10-31-2012, 02:53 AM   #3
micflunu
Member
 
Registered: Oct 2012
Posts: 73

Original Poster
Rep: Reputation: Disabled
I did this in my parse function

char parse(char buffer[],int num_of_args, char *arguments[num_of_args +1])
{
arguments=NULL;
for(int i=0;i<num_of_args+1;i++){`enter code here`
do
{
arguments = strtok(buffer, " ");
}
while(arguments!=NULL);
}
return arguments;
}
buffer[] is the array i saved the user input from the fgets() in main ,num_of_args is the result of my counter function called in main and ....... but it is producentg the following error ./myshell.c: In function ‘parse’:
./myshell.c:20:8: error: ‘for’ loop initial declarations are only allowed in C99 mode
./myshell.c:20:8: note: use option -std=c99 or -std=gnu99 to compile your code
./myshell.c:23:27: warning: assignment from incompatible pointer type
./myshell.c:27:1: warning: return makes integer from pointer without a cast
what is wrong??cld any one help??
 
Old 10-31-2012, 03:31 AM   #4
Heraton
Member
 
Registered: Apr 2011
Location: Germany
Distribution: Mint 10, openSuSE
Posts: 58

Rep: Reputation: 3
This and that...

Hi!

Now I am sure this thread should be in programming, as you seem to have still hard times with c.

Code:
./myshell.c:20:8: error: ‘for’ loop initial declarations are only allowed in C99 mode
./myshell.c:20:8: note: use option -std=c99 or -std=gnu99 to compile your code
Without looking into it, this error message is pretty self-explanatory. Standard c does not allow to your use of c++-style for-loops. Use
Code:
int i;
for(i=0;i<num_of_args+1;i++)
instead of
Code:
for(int i=0;i<num_of_args+1;i++)
like I did in my example. Standard does not allow to declare a variable in the head of a for loop.

Code:
./myshell.c:23:27: warning: assignment from incompatible pointer type
This one is another c classic. This
Code:
arguments = strtok(buffer, " ");
is an attempt to assign a char pointer to an array of char pointers if my flu is not playing tricks on me.

Code:
./myshell.c:27:1: warning: return makes integer from pointer without a cast
Your parsing function has the return type char, which is a numeric value. Your arguments is a pointer variable. Therefore you get the warning, that the c compiler is going to use that pointer value (not the value the pointer points to) as an integer value.

Regards, Heraton
 
Old 10-31-2012, 04:46 AM   #5
micflunu
Member
 
Registered: Oct 2012
Posts: 73

Original Poster
Rep: Reputation: Disabled
tnx sooo much for the replay it worked for the first answer u gave me
int i;
for(i=.......) but i think i didn,t understand what u are tring to tell me after that but i changed
return argument;
to
return *argument; if that is what u mean... but i still got error message

./myshell.c:24:27: warning: assignment from incompatible pointer type
./myshell.c:28:1: warning: return makes integer from pointer without a cast

pla i am new to this course so help me.
i really appreciate it. tnx!!!
 
Old 10-31-2012, 05:18 AM   #6
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Slackware 10.1/10.2/12, Ubuntu 12.04, Crunchbang Statler
Posts: 3,786

Rep: Reputation: 282Reputation: 282Reputation: 282
Undo your last change. Next change
Code:
char parse(char buffer[],int num_of_args, char *arguments[num_of_args +1])
{
to
Code:
char *parse(char buffer[],int num_of_args, char *arguments[num_of_args +1])
{
Please learn to use code tags when posting code on the forum; it makes code easier to read.
[code]your code here[/code] results in
Code:
your code here
PS
There is a dedicated programming section at LQ where future coding related questions might fit better
 
Old 10-31-2012, 05:40 AM   #7
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 9,339

Rep: Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747
I think this line is not ok at all:
Code:
char *parse(char buffer[],int num_of_args, char *arguments[num_of_args +1])
You are not really allowed to pass such constructs, you should do something like this:
Code:
char *parse(char buffer[],int num_of_args, char *arguments[])
 
Old 10-31-2012, 05:50 AM   #8
micflunu
Member
 
Registered: Oct 2012
Posts: 73

Original Poster
Rep: Reputation: Disabled
Code:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<stdio.h>
#include<stdarg.h>
 int countArgs(char n_args[], ...){
        va_list ap;
        int i, t;
        va_start(ap, n_args);
        for(i=0;t = va_arg(ap, int);i++){
               return  t;
        }
      va_end(ap);
	}
char *parse(char buffer[],int num_of_args, char *arguments[])
    { 
       arguments=NULL;
       int i;
       for(i=0;i<num_of_args+1;i++){
             do 
               {
                arguments = strtok(buffer, " ");
                      }
                  while(arguments!=NULL);
               }
return arguments;
 }

int main(int argc, char **argv)
	{
	        //buffer is to hold the commands that the user will type in
	        char buffer[512];
	        // /bin/program_name is the arguments to pass to execv
	        //if we want to run ls, "/bin/ls" is required to be passed to execv()
	        char *path = "/bin/";
	 
	        while(1)
	        {
	                //print the prompt
	                printf("myShell&gt;");
	                //get input
	                fgets(buffer, 512, stdin);
	                //fork!
	                int pid = fork();	                //Error checking to see if fork works
	                //If pid !=0 then it's the parent
	                if(pid!=0)
	                {
	                        wait(NULL);
	                }
	                else
	                {
	                        //if pid = 0 then we're at teh child
	                        //Count the number of arguments
	                        int num_of_args = countArgs(buffer);
	                        //create an array of pointers for the arguments to be passed to execcv.
	                        char *arguments[num_of_args+1];
	                        //parse the input and arguments will have all the arguments to be passed to the program
	                        parse(buffer, num_of_args, arguments);	                        //set the last pointer in the array to NULL. Requirement of execv
	                        arguments[num_of_args] = NULL;
	                        //This will be the final path to the program that we will pass to execv
	                        char prog[512];
	                        //First we copy a /bin/ to prog
	                        strcpy(prog, path);
	                        //Then we concancate the program name to /bin/
	                        //If the program name is ls, then it'll be /bin/ls
	                        strcat(prog, arguments[0]);
	                        //pass the prepared arguments to execv and we're done!
	                        int rv = execv(prog, arguments);
	                }
	        }
	        return 0;
}
Tnx sooo much for ur replay. And sorry i willdo that.I didid what u tald me to do but it isn, working it keeps giving me this...

Code:
./myshell.c: In function ‘parse’:
./myshell.c:24:27: warning: assignment from incompatible pointer type
./myshell.c:28:1: warning: return from incompatible pointer type
what do u think cld u check out the whole code pls??

Last edited by micflunu; 10-31-2012 at 06:10 AM.
 
Old 10-31-2012, 09:49 AM   #9
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 9,339

Rep: Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747Reputation: 2747
if you really want to say thanks please press yes (bottom right corner of the post).
In line 17 you tries yo pass char *arguments[]. in line 19 I found the following: arguments=NULL; I think you should use another variable here, you need to resolve this conflict (that caused the warning on line 28 too)
 
Old 11-01-2012, 01:44 AM   #10
micflunu
Member
 
Registered: Oct 2012
Posts: 73

Original Poster
Rep: Reputation: Disabled
tnx i will do that but i think i did n,t get what u tring to tell me.cld u pls elaborate a little???
tnx
 
Old 11-01-2012, 02:05 AM   #11
micflunu
Member
 
Registered: Oct 2012
Posts: 73

Original Poster
Rep: Reputation: Disabled
i changed the parsing function to this


Code:
char *parse(char buffer[],int num_of_args, char *arguments[])
    { 
       arguments[num_of_args+1]=NULL;
       int i;
       for(i=0;i<num_of_args+1;i++){
             do 
               {
                arguments[i]= strtok(buffer, " ");
              return arguments[i];
                      }
                  while(arguments!=NULL);
               }

 }
there is no error but there is no result either.it is not working as it was supposed to meaning executing the user inputed commands.Cld any one help me ?pls
 
Old 11-01-2012, 04:27 AM   #12
micflunu
Member
 
Registered: Oct 2012
Posts: 73

Original Poster
Rep: Reputation: Disabled
Smile

i have solved it my self the problem was
the second argument of strcat was of type const char* but i was trying trying to pass an array of char so i did the following changes
Code:
do 
               {
                arguments[i]= strtok(buffer, " ");
               return arguments[i];
                      }
                  while(arguments!=NULL);
               }
in the parse function and
Code:
           int i;
                                 for (i=0; i<num_of_args; i++) {
                                  strcat(prog, arguments[i]);
                                   int rv = execv(prog, arguments);
                                   }
 
Old 11-01-2012, 09:40 AM   #13
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
The programing forum might have been a better choice than Linux Newbies.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
BASH script using getopt to parse optional arguments nano2 General 6 04-28-2011 08:09 AM
PHP Error Parse error: parse error, unexpected $ in /home/content/S/k/i/SkinCare4U/h CowanServices Programming 2 12-09-2008 08:26 PM
Parse error: parse error, unexpected '}' in /home/content jouvert Linux - Newbie 3 05-17-2008 06:55 PM
Parse error: parse error, unexpected $ in /home/content/d/o/m/domain/html/addpuppy2.p Scooby-Doo Programming 3 10-25-2007 09:41 AM
Symbolic links that pass commandline arguments to busybox jgombos Linux - General 1 11-07-2006 10:09 AM


All times are GMT -5. The time now is 12:44 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration