I have a very big string "-dAwin Main_Window -dwin Widget_Window -dh 500 -dw 300 -da 100 -dv 10 -dint 2............"

This string gives me input parameter for running my application.Example -dAwin Main_Window gives me application window name. -dAwin is identifier b'coz this sequence may change or number of parameters may change.

I have to parse this string and fill these parameters in the structure.Example I have to parse -dh 500 and fill height element in the structure.I can parse this string but logic is becoming very complex and again

Let me know if you have any simple approach.Reply if you are too busy with your work.


Regards,
Anand Shah

Recommended Answers

All 14 Replies

You need to create a structure that will be the element name on one side and the element value on the other.
Make an array of those structs and fill the structs with values from the command-line.

Once you have loaded that structure, then you can loop through it and evaluate the parameters.

see: strtok, see: struct

What is your field (struct member is also a field), separator? Hyphen, space, maybe both?

Here's a trick:
Initialize all your fields in the struct to 0 or '\0'.

Print out some strings. Put a vertical line between each field, with a pencil |.

Now you can loop through the buffer holding the string, as many times as you need to, parsing out one field at a time.

When it's all working for even the most difficult strings, then integrate the code enough to make it more efficient, but keep it clear enough that you can readily understand it.

You may need to change this code, if the string format ever changes in the future.

You need to create a structure that will be the element name on one side and the element value on the other.
Make an array of those structs and fill the structs with values from the command-line.

Once you have loaded that structure, then you can loop through it and evaluate the parameters.

see: strtok, see: struct

Hi thines01,
Can you please elaborate more on this ???

What is your field (struct member is also a field), separator? Hyphen, space, maybe both?

Here's a trick:
Initialize all your fields in the struct to 0 or '\0'.

Print out some strings. Put a vertical line between each field, with a pencil |.

Now you can loop through the buffer holding the string, as many times as you need to, parsing out one field at a time.

When it's all working for even the most difficult strings, then integrate the code enough to make it more efficient, but keep it clear enough that you can readily understand it.

You may need to change this code, if the string format ever changes in the future.

Hi Adak,
How to parse one field at a time more efficiently ???

Here is a crude form of what I'm describing:
A structure that assumes no name or value will be larger than 16 bytes

#include <stdio.h>
#include <string.h>

typedef struct tagCL_PARAMS
{
	char strName[16];
	char strValue[16];
} CL_PARAMS;

/* then inside your program you can create an array of those either based
on a static amount or dynamically created based on the value of argc */

int main(int argc, char** argv)
{
	auto int i = 0;
	auto CL_PARAMS arrClParams[32] = {};

	for(i=1; i<argc; i+=2)
	{
		strcpy(arrClParams[i-1].strName, argv[i]);
		strcpy(arrClParams[i-1].strValue, argv[i+1]);
	}
}

PLEASE - don't start this with code - FORGET THE CODE FOR NOW!

Start with carefully studying the problem, in this case, the strings. KNOW those strings - know what are the separators between the fields, know how many fields they might have AT THE MOST.

STUDY & KNOW the problem, until you know how to solve it. Then set up the logic you used, to solve it. Put that logic into a flowchart or pseudo code, so each step of an algorithm to solve the problem, can be identified.

THEN write your code (which should spring right out from the pseudo code or flowchart).

Put off all the details, and get the flow of the program, and the functions you want for it, set up. Check your work as you go for any compiler warnings or errors, and for the accuracy of the program, so far.

Then add your details that you put off, and make any final little adjustments (typically, this will be to the look and feel of the interface).

Welcome to Top Down design! ;)

When you say:

A structure that assumes no name or value will be larger than 16 bytes

Who says you want char's? Why 16 bytes? That looks so much like a "magical number" you just pulled out of the hat.

Start with the strings, Luke! Turn off your target acquisition system in your X-wing fighter! ;)

Yes, Adak, I pulled those values (widths) out of the air.
An alternative would be to explain pointers and give an example MUCH more complicated (or no example at all).

The complication might have been reduced if I'm sure of the origin of the parameters.

Yes, it's a crude example, but I gave a warning ;)

Yes, you did, and my warnings were not intended for your example, but for Pinkannu. I don't want to see code from the OP, until after the problem has been thoroughly studied, and the logic to solve it, has been found.

Hi Adak & thines01,
Thanks for your help.But I have another problem.I am not getting input parameters in argv.They are coming as a string.So I can not do something like below.

for(i=1; i<argc; i+=2)
{
strcpy(arrClParams[i-1].strName, argv[i]);
strcpy(arrClParams[i-1].strValue, argv[i+1]);
}

I don't even know what the blazes you're doing with that code. *Argv[] is an array of pointers to char, so it should work fine with a string.

Forget code for a second. Show several strings as examples of your input. Then show the output that you want. Then show the pseudo code logic that you plan on using in your program to make that happen.

I know as a beginner, the C syntax can be a major hurdle, but ignore it for right now. Assume that you can get the syntax to work, with a little help, and it's not a problem. Concentrate on the logic, and program flow of that logic.

"Concentrate on the force, Luke!" ;)

Hi Adak,
following are the details.
1.I am launching another process from my application.
2.While launching I will pass shared memory name where input parameter string is placed.i.e parameter sharing is done using shared memory.
3.So in launched process I will get shared memory name in argv.I will open that memory and copy string to local character array.
4.Then I have to parse this string Ex.

"-dAwin Main_Window -dh 200 -dw 500 ...."

where -dAwin -> Application window name
-dh -> Window height
-dv -> Window width.
-dAwin , -dh , -dw are the identifiers and they are followed by corresponding values.
5.I have to parse this string and fill following structure.

struct Input_Param
{
   char ApWinName[255];
   int  Height ;
   int width;
};

This is just a sample.I have around 30 such parameters to parse.So string is quite big.

Note :- I am getting only shared memory name in char **argv.Also sequence and length may change.So I can not assume string will always come as shown in above example. It can come as shown below.

"-dw 500 -dAwin Main_Window -dh 200  ...."   " -dAwin Main_Window -dh 200  ...."

Waiting for your post.

Focus on one thing at a time - in this case, parsing the string.

Looks like -dH is the field identifier for your struct, where "H" represents a unique handle {w, Win, h, etc.}.

So make a list of these field id's: -dh, -dw, -dWin, etc., and use strstr() to return a pointer to them, wherever they are, in the string. Use that pointer to then assign the value they point to, to your struct fields.

You'll need to include <string.h> for strstr(), and use sscanf() to store your value (since it is formatted data) from a string). Make your buffer plenty large enough to handle one string - maybe BUFSIZ (which varies from system to system, but 512 chars size is common these days). (BUFSIZ is a macro).

Heaven help us, shared memory. You couldn't just pass the string to a function?

Anyway, one thing at a time, let's get the parse going locally, and then rest, later.

If you simply need to parse the string and still have key/value pairs, I suggest using strtok(). Get odd-numbered tokens as the key and even-numbered tokens as the value. Once you get the left-side, you can remove or ignore the -d and evaluate the key.

#include<stdio.h>
#include<string.h>

int main(void)
{
	char pstrInput[] = "-dAwin Main_Window -dwin Widget_Window -dh 500 -dw 300 -da 100 -dv 10 -dint 2";
	char* pstrSeps = " \t\r\n";
	static char* pstrToken = 0;
	int	iTokenCount=0;

	pstrToken = strtok(pstrInput, pstrSeps);
	
	while(pstrToken)
	{
		if(iTokenCount%2 ==0)
		{	//left (key) side
			printf("%s=", pstrToken);
		}
		else
		{	//right (value) side
			printf("%s\n", pstrToken);
		}

		++iTokenCount;
		pstrToken = strtok(0, pstrSeps);
	}
	return 0;
}

If you simply need to parse the string and still have key/value pairs, I suggest using strtok(). Get odd-numbered tokens as the key and even-numbered tokens as the value. Once you get the left-side, you can remove or ignore the -d and evaluate the key.

#include<stdio.h>
#include<string.h>

int main(void)
{
	char pstrInput[] = "-dAwin Main_Window -dwin Widget_Window -dh 500 -dw 300 -da 100 -dv 10 -dint 2";
	char* pstrSeps = " \t\r\n";
	static char* pstrToken = 0;
	int	iTokenCount=0;

	pstrToken = strtok(pstrInput, pstrSeps);
	
	while(pstrToken)
	{
		if(iTokenCount%2 ==0)
		{	//left (key) side
			printf("%s=", pstrToken);
		}
		else
		{	//right (value) side
			printf("%s\n", pstrToken);
		}

		++iTokenCount;
		pstrToken = strtok(0, pstrSeps);
	}
	return 0;
}

Thankk you very much Adak and Thines01

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.