Breaking strings apart

N

noridotjabi

I'm working on a prompt style thing and I need a way to pass arguments
to commands within my program. For example:

::hello -v -r -n

If this is entered as one input string, can I (in any simple way) break
it apart so I have something like:

str[0] = "hello"
str[1] = "-v"
str[2] = "-r"
str[3] = "-n"

This way say I had a command connect I could do this:

::connect 0.0.0.0 0

And later use this to connect to the internet by saying okay str[0] =
"connect" so connect str[1] = "0.0.0.0" so connect to 0.0.0.0 str[2] =
"0" so connect to 0.0.0.0 on port 0. Thanks.
Nori

P.S. My question is not related to network programing it was simply an
example. I am well aware how to code this on my own I just need some
way to get input from the user properly.
 
C

C. Benson Manica

::hello -v -r -n

If this is entered as one input string, can I (in any simple way) break
it apart so I have something like:

str[0] = "hello"
str[1] = "-v"
str[2] = "-r"
str[3] = "-n"

Sure, assuming str is defined appropriately, say as a char **.
Assuming your command line is space-delimited, and you feel adequate to
the task, strtok() can do what you want.
 
P

pete

I'm working on a prompt style thing and I need a way to pass arguments
to commands within my program. For example:

::hello -v -r -n
I just need some
way to get input from the user properly.

/* BEGIN pops_device.c */
/*
** If rc equals 0, then an empty line was entered
** and the array contains garbage.
** If rc equals EOF, then the end of file was reached.
** If rc equals 1, then there is a string in array.
** Up to LENGTH number of characters are read
** from a line of a text file or stream.
** If the line is longer than LENGTH,
** then the extra characters are discarded.
*/
#include <stdio.h>

#define LENGTH 80
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
int rc;
char array[LENGTH + 1];

puts("The LENGTH macro is " xstr(LENGTH));
fputs("Enter a string with spaces:", stdout);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getchar();
}
while (rc == 1) {
printf("Your string is:%s\n\n"
"Hit the Enter key to end,\nor enter "
"another string to continue:", array);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getchar();
}
if (rc == 0) {
*array = '\0';
}
}
return 0;
}

/* END pops_device.c */
 
V

Vladimir Oka

I'm working on a prompt style thing and I need a way to pass arguments
to commands within my program. For example:

::hello -v -r -n

If this is entered as one input string, can I (in any simple way) break
it apart so I have something like:

str[0] = "hello"
str[1] = "-v"
str[2] = "-r"
str[3] = "-n"


7.21.5.8 p 1 & 2

#include <string.h>

char *strtok(char * restrict s1, const char * restrict s2);

A sequence of calls to the strtok function breaks the string
pointed to by s1 into a sequence of tokens, each of which
is delimited by a character from the string pointed to
by s2. The first call in the sequence has a non-null first
argument; subsequent calls in the sequence have a null first
argument. The separator string pointed to by s2 may be
different from call to call.

Look it up in your manual or the Standard.
 
C

CBFalconer

I'm working on a prompt style thing and I need a way to pass
arguments to commands within my program. For example:

::hello -v -r -n

If this is entered as one input string, can I (in any simple way)
break it apart so I have something like:

str[0] = "hello"
str[1] = "-v"
str[2] = "-r"
str[3] = "-n"
.... snip ...

Try the following. You can easily create the toksplit.h file for
yourself. Another possibility is the standard function strtok,
which has some nuisance characteristics.

/* ------- file toksplit.c ----------*/
#include "toksplit.h"

/* copy over the next token from an input string, after
skipping leading blanks (or other whitespace?). The
token is terminated by the first appearance of tokchar,
or by the end of the source string.

The caller must supply sufficient space in token to
receive any token, Otherwise tokens will be truncated.

Returns: a pointer past the terminating tokchar.

This will happily return an infinity of empty tokens if
called with src pointing to the end of a string. Tokens
will never include a copy of tokchar.

A better name would be "strtkn", except that is reserved
for the system namespace. Change to that at your risk.

released to Public Domain, by C.B. Falconer.
Published 2006-02-20. Attribution appreciated.
*/

const char *toksplit(const char *src, /* Source of tokens */
char tokchar, /* token delimiting char */
char *token, /* receiver of parsed token */
size_t lgh) /* length token can receive */
/* not including final '\0' */
{
if (src) {
while (' ' == *src) *src++;

while (*src && (tokchar != *src)) {
if (lgh) {
*token++ = *src;
--lgh;
}
src++;
}
if (*src && (tokchar == *src)) src++;
}
*token = '\0';
return src;
} /* toksplit */

#ifdef TESTING
#include <stdio.h>

#define ABRsize 6 /* length of acceptable token abbreviations */

int main(void)
{
char teststring[] = "This is a test, ,, abbrev, more";

const char *t, *s = teststring;
int i;
char token[ABRsize + 1];

puts(teststring);
t = s;
for (i = 0; i < 4; i++) {
t = toksplit(t, ',', token, ABRsize);
putchar(i + '1'); putchar(':');
puts(token);
}

puts("\nHow to detect 'no more tokens'");
t = s; i = 0;
while (*t) {
t = toksplit(t, ',', token, 3);
putchar(i + '1'); putchar(':');
puts(token);
i++;
}

puts("\nUsing blanks as token delimiters");
t = s; i = 0;
while (*t) {
t = toksplit(t, ' ', token, ABRsize);
putchar(i + '1'); putchar(':');
puts(token);
i++;
}
return 0;
} /* main */

#endif
/* ------- end file toksplit.c ----------*/

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
V

Vladimir Oka

Vladimir said:
I'm working on a prompt style thing and I need a way to pass arguments
to commands within my program. For example:

::hello -v -r -n

If this is entered as one input string, can I (in any simple way) break
it apart so I have something like:

str[0] = "hello"
str[1] = "-v"
str[2] = "-r"
str[3] = "-n"


7.21.5.8 p 1 & 2

#include <string.h>

char *strtok(char * restrict s1, const char * restrict s2);

A sequence of calls to the strtok function breaks the string
pointed to by s1 into a sequence of tokens, each of which
is delimited by a character from the string pointed to
by s2. The first call in the sequence has a non-null first
argument; subsequent calls in the sequence have a null first
argument. The separator string pointed to by s2 may be
different from call to call.

Look it up in your manual or the Standard.

If you don't need to stick to standard functions, have look at
`getopt()`. Googling for it should take you to someplace useful. I know
it's part of GNU C Library, but it should be available more widely as
well.
 
N

noridotjabi

I guess I don't understand what would go in the toksplit.h file or even
why it would be nessisary: it worked fine without it. If you could
elaborate it would be much apreciated. Also thanks really good
example.
Nori
I'm working on a prompt style thing and I need a way to pass
arguments to commands within my program. For example:

::hello -v -r -n

If this is entered as one input string, can I (in any simple way)
break it apart so I have something like:

str[0] = "hello"
str[1] = "-v"
str[2] = "-r"
str[3] = "-n"
... snip ...

Try the following. You can easily create the toksplit.h file for
yourself. Another possibility is the standard function strtok,
which has some nuisance characteristics.

/* ------- file toksplit.c ----------*/
#include "toksplit.h"

/* copy over the next token from an input string, after
skipping leading blanks (or other whitespace?). The
token is terminated by the first appearance of tokchar,
or by the end of the source string.

The caller must supply sufficient space in token to
receive any token, Otherwise tokens will be truncated.

Returns: a pointer past the terminating tokchar.

This will happily return an infinity of empty tokens if
called with src pointing to the end of a string. Tokens
will never include a copy of tokchar.

A better name would be "strtkn", except that is reserved
for the system namespace. Change to that at your risk.

released to Public Domain, by C.B. Falconer.
Published 2006-02-20. Attribution appreciated.
*/

const char *toksplit(const char *src, /* Source of tokens */
char tokchar, /* token delimiting char */
char *token, /* receiver of parsed token */
size_t lgh) /* length token can receive */
/* not including final '\0' */
{
if (src) {
while (' ' == *src) *src++;

while (*src && (tokchar != *src)) {
if (lgh) {
*token++ = *src;
--lgh;
}
src++;
}
if (*src && (tokchar == *src)) src++;
}
*token = '\0';
return src;
} /* toksplit */

#ifdef TESTING
#include <stdio.h>

#define ABRsize 6 /* length of acceptable token abbreviations */

int main(void)
{
char teststring[] = "This is a test, ,, abbrev, more";

const char *t, *s = teststring;
int i;
char token[ABRsize + 1];

puts(teststring);
t = s;
for (i = 0; i < 4; i++) {
t = toksplit(t, ',', token, ABRsize);
putchar(i + '1'); putchar(':');
puts(token);
}

puts("\nHow to detect 'no more tokens'");
t = s; i = 0;
while (*t) {
t = toksplit(t, ',', token, 3);
putchar(i + '1'); putchar(':');
puts(token);
i++;
}

puts("\nUsing blanks as token delimiters");
t = s; i = 0;
while (*t) {
t = toksplit(t, ' ', token, ABRsize);
putchar(i + '1'); putchar(':');
puts(token);
i++;
}
return 0;
} /* main */

#endif
/* ------- end file toksplit.c ----------*/

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
C

CBFalconer

*** top-posting fixed ***
CBFalconer said:
I'm working on a prompt style thing and I need a way to pass
arguments to commands within my program. For example:

::hello -v -r -n

If this is entered as one input string, can I (in any simple way)
break it apart so I have something like:

str[0] = "hello"
str[1] = "-v"
str[2] = "-r"
str[3] = "-n"
... snip ...

Try the following. You can easily create the toksplit.h file for
yourself. Another possibility is the standard function strtok,
which has some nuisance characteristics.

/* ------- file toksplit.c ----------*/
#include "toksplit.h"

/* copy over the next token from an input string, after
skipping leading blanks (or other whitespace?). The
token is terminated by the first appearance of tokchar,
or by the end of the source string.

The caller must supply sufficient space in token to
receive any token, Otherwise tokens will be truncated.

Returns: a pointer past the terminating tokchar.

This will happily return an infinity of empty tokens if
called with src pointing to the end of a string. Tokens
will never include a copy of tokchar.

A better name would be "strtkn", except that is reserved
for the system namespace. Change to that at your risk.

released to Public Domain, by C.B. Falconer.
Published 2006-02-20. Attribution appreciated.
*/

const char *toksplit(const char *src, /* Source of tokens */
char tokchar, /* token delimiting char */
char *token, /* receiver of parsed token */
size_t lgh) /* length token can receive */
/* not including final '\0' */
{
if (src) {
while (' ' == *src) *src++;

while (*src && (tokchar != *src)) {
if (lgh) {
*token++ = *src;
--lgh;
}
src++;
}
if (*src && (tokchar == *src)) src++;
}
*token = '\0';
return src;
} /* toksplit */

#ifdef TESTING
#include <stdio.h>

#define ABRsize 6 /* length of acceptable token abbreviations */

int main(void)
{
char teststring[] = "This is a test, ,, abbrev, more";

const char *t, *s = teststring;
int i;
char token[ABRsize + 1];

puts(teststring);
t = s;
for (i = 0; i < 4; i++) {
t = toksplit(t, ',', token, ABRsize);
putchar(i + '1'); putchar(':');
puts(token);
}

puts("\nHow to detect 'no more tokens'");
t = s; i = 0;
while (*t) {
t = toksplit(t, ',', token, 3);
putchar(i + '1'); putchar(':');
puts(token);
i++; *>> }

puts("\nUsing blanks as token delimiters");
t = s; i = 0;
while (*t) {
t = toksplit(t, ' ', token, ABRsize);
putchar(i + '1'); putchar(':');
puts(token);
i++;
}
return 0;
} /* main */

#endif
/* ------- end file toksplit.c ----------*/

I guess I don't understand what would go in the toksplit.h file
or even why it would be nessisary: it worked fine without it.
If you could elaborate it would be much apreciated. Also thanks
really good example.

The toksplit.h file would normally contain the prototype for
toksplit, and thus be available for inclusion in another source
file that uses the routine. Gussied up with such things as
multi-inclusion protection, etc. The result is:

/* ------- file toksplit.h ----------*/
#ifndef H_toksplit_h
# define H_toksplit_h

# ifdef __cplusplus
extern "C" {
# endif

#include <stddef.h>

/* copy over the next token from an input string, after
skipping leading blanks (or other whitespace?). The
token is terminated by the first appearance of tokchar,
or by the end of the source string.

The caller must supply sufficient space in token to
receive any token, Otherwise tokens will be truncated.

Returns: a pointer past the terminating tokchar.

This will happily return an infinity of empty tokens if
called with src pointing to the end of a string. Tokens
will never include a copy of tokchar.

released to Public Domain, by C.B. Falconer.
Published 2006-02-20. Attribution appreciated.
*/

const char *toksplit(const char *src, /* Source of tokens */
char tokchar, /* token delimiting char */
char *token, /* receiver of parsed token */
size_t lgh); /* length token can receive */
/* not including final '\0' */

# ifdef __cplusplus
}
# endif
#endif
/* ------- end file toksplit.h ----------*/

Glad to see you have learned to properly include context from the
google excuse for an interface. Now you also need to learn that
your answer belongs after, or possibly intermixed with, the
material you quote. You should also normally snip anything out of
the quoted material that is not germane to your answer.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top