How to change handle range of integer

M

moonhkt

Hi All

How to using C to change input value "0-4,10,20,40-45" to to
"0,1,2,3,4,10,20,40,41,42,43,44,45" ?

moonhkt
 
T

Tom St Denis

Hi All

How to using C to change input value "0-4,10,20,40-45" to  to
"0,1,2,3,4,10,20,40,41,42,43,44,45" ?

moonhkt

By finishing your homework assignment yourself.

Tom
 
K

Keith Thompson

moonhkt said:
How to using C to change input value "0-4,10,20,40-45" to to
"0,1,2,3,4,10,20,40,41,42,43,44,45" ?

By writing a program to do it.

Show us what you've done, and we'll be glad to help.
 
M

moonhkt

By writing a program to do it.

Show us what you've done, and we'll be glad to help.

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Try to read crontab file , build run schedule by month.


/* gcc str_split.c -o str_split */

#include <stdio.h>
#include <io.h>
#include <fcntl.h>

#define MAX_FIELD_SIZE 1023


typedef unsigned char bool;

enum { UNSELECTED=0, COLUMN, FIELD } ModeType;

bool field_list[MAX_FIELD_SIZE]; /* list of selected fields */
bool SupressFlag = 0; /* supress lines without delimiter symbol */
// num ModeType mode = UNSELECTED; /* scan mode: column vs. field */
unsigned char delimiter = '\t'; /* delimiter symbol for field
separation */


int Set_list();

void main (int argc, char **argv)
{
int error = 0;

char *p;
p = "0-4,10,20,40-45";
printf("main() %-30s\n",p); // p only
error = Set_list(p); // p only
printf("error = %3d\n", error);

printf("# %-30s\n",field_list[1]);


}

/*
* Set_list - Parse field argument list and set selected fields
*/
int Set_list (char *list)
{
bool setFieldFlag = 0; /* flag to indicate if any fields were set */
bool contFlag = 0; /* flag to continue setting fields for a range (i-
j) */
unsigned prevField = 0; /* previous field selected */
unsigned field; /* field position */

while (*list)
{
switch (*list) {
case '-':
if (contFlag) return(1);
contFlag = 1; /* turn on continue flag */
list++;
break;
case ',':
contFlag = 0;
list++;
break;
default:
field = 0;
while (*list >= '0' && *list <= '9')
{
field *= 10;
field += *list - '0';
++list;
}
if (field == 0) return(1);
else if (field > MAX_FIELD_SIZE) return(2);
--field; /* decrement field # for array index */
if (!contFlag) prevField = field;
else contFlag = 0;
while (prevField <= field)
{
field_list[prevField++] = 1;
}
setFieldFlag = 1; /* set field selected flag
*/
} /* end switch */
} /* end while */

if (contFlag)
{
while (prevField <= MAX_FIELD_SIZE)
{
field_list[prevField++] = 1;
}
}

if (setFieldFlag == 0) return 1; /* error - nothing selected
*/
else return 0; /* okay */
} /* end Set_list */
 
B

Ben Bacarisse

It's better to snip sig blocks.
Try to read crontab file , build run schedule by month.

Why are you using C to do this? It looks like an ideal fit for a
scripting language.
/* gcc str_split.c -o str_split */

#include <stdio.h>
#include <io.h>
#include <fcntl.h>

These look odd. A simple text processing program like this should not
need anything other than standard headers.
#define MAX_FIELD_SIZE 1023


typedef unsigned char bool;

enum { UNSELECTED=0, COLUMN, FIELD } ModeType;

bool field_list[MAX_FIELD_SIZE]; /* list of selected fields */
bool SupressFlag = 0; /* supress lines without delimiter symbol */
// num ModeType mode = UNSELECTED; /* scan mode: column vs. field */
unsigned char delimiter = '\t'; /* delimiter symbol for field
separation */

It's a shame to use globals. If you stick with C for scripts like this,
one day you'll want to put this code into a bigger program and a clean
functional API will make that easier.
int Set_list();

This is not a prototype and prototypes are a Good Thing.
void main (int argc, char **argv)
s/void/int/

{
int error = 0;

char *p;
p = "0-4,10,20,40-45";
printf("main() %-30s\n",p); // p only
error = Set_list(p); // p only
printf("error = %3d\n", error);

printf("# %-30s\n",field_list[1]);


}

/*
* Set_list - Parse field argument list and set selected fields

At least tell reader what that returned int means. BTW, "argument list"
usually means something else in C. I'd say "parse fields from a
string".
*/
int Set_list (char *list)
{
bool setFieldFlag = 0; /* flag to indicate if any fields were set */
bool contFlag = 0; /* flag to continue setting fields for a range (i-
j) */
unsigned prevField = 0; /* previous field selected */
unsigned field; /* field position */

while (*list)
{
switch (*list) {
case '-':
if (contFlag) return(1);
contFlag = 1; /* turn on continue flag */
list++;
break;
case ',':
contFlag = 0;
list++;
break;
default:
field = 0;
while (*list >= '0' && *list <= '9')
{
field *= 10;
field += *list - '0';
++list;
}
if (field == 0) return(1);

I have not looked at the rest in detail, but this jumps out at me.
return 1 is an error, yes? field can be zero quite legitimately. In
fact it is the first field in your test case.
else if (field > MAX_FIELD_SIZE) return(2);
--field; /* decrement field # for array index */
if (!contFlag) prevField = field;
else contFlag = 0;
while (prevField <= field)
{
field_list[prevField++] = 1;
}
setFieldFlag = 1; /* set field selected flag
*/
} /* end switch */
} /* end while */

if (contFlag)
{
while (prevField <= MAX_FIELD_SIZE)
{
field_list[prevField++] = 1;
}
}

if (setFieldFlag == 0) return 1; /* error - nothing selected
*/
else return 0; /* okay */
} /* end Set_list */
 
K

Kenny McCormack

Try to read crontab file , build run schedule by month.

(Rest snipped)

Why do this in C at all?

Assuming you're doing it because you want it done and not just as an
exercise (and a stupid one at that), you should be doing it in AWK or
Perl (or Python or Ruby or whatever).
 
J

James Dow Allen

moonhkt <[email protected]> might have writ, in (e-mail address removed):

In addition to what Ben pointed out, your problem is here:
bool field_list[MAX_FIELD_SIZE]; /* list of selected fields */
printf("# %-30s\n",field_list[1]);

%s wants char *, you're giving it bool (unsigned char).
When you fix this, remember that it is '1' (not 1) that prints as 1.

(e-mail address removed) (Kenny McCormack) might have writ, in
Why do this in C at all?

Assuming you're doing it because you want it done and not just as an
exercise (and a stupid one at that), you should be doing it in AWK or
Perl (or Python or Ruby or whatever).

Am I the only one who finds this suggestion particularly annoying?
I've never learned Perl (or whatever), and am happy to use C even
when better languages exist. I'm not fully too lazy to learn; the last
several languages I learned included LaTex, Mathematica, Html, Css
and Javascript. I also enjoy learning some linguistics, ancient
history, etc. I wish I weren't so lazy and had learned even more.
I'd have liked to learn juggling, piano playing, and several more of
the Kama Sutra positions.

To pretend that everyone who wants to be an adept C programmer need
also be adept at Perl (or whatever) is almost preciously pretentious.

And why is this a "stupid" exercise? It's an easy exercise, yes, but
for its level of difficulty I don't know why it's particularly "stupid."
 
B

Barry Schwarz

Try to read crontab file , build run schedule by month.


/* gcc str_split.c -o str_split */

#include <stdio.h>
#include <io.h>
#include <fcntl.h>

#define MAX_FIELD_SIZE 1023


typedef unsigned char bool;

enum { UNSELECTED=0, COLUMN, FIELD } ModeType;

bool field_list[MAX_FIELD_SIZE]; /* list of selected fields */
bool SupressFlag = 0; /* supress lines without delimiter symbol */
// num ModeType mode = UNSELECTED; /* scan mode: column vs. field */
unsigned char delimiter = '\t'; /* delimiter symbol for field
separation */


int Set_list();

void main (int argc, char **argv)
{
int error = 0;

char *p;
p = "0-4,10,20,40-45";
printf("main() %-30s\n",p); // p only
error = Set_list(p); // p only
printf("error = %3d\n", error);

printf("# %-30s\n",field_list[1]);

This can't be what you want. %s requires a pointer to char.
field_list[1] is an unsigned char. This invokes undefined behavior.

Furthermore, Set_list stores integer values in field_list which are
not printable as characters. 1 is not the same a '1'.
}

/*
* Set_list - Parse field argument list and set selected fields
*/
int Set_list (char *list)
{
bool setFieldFlag = 0; /* flag to indicate if any fields were set */
bool contFlag = 0; /* flag to continue setting fields for a range (i-
j) */
unsigned prevField = 0; /* previous field selected */
unsigned field; /* field position */

while (*list)
{
switch (*list) {
case '-':
if (contFlag) return(1);
contFlag = 1; /* turn on continue flag */
list++;
break;

Your indenting is not achieving its intended purpose. It should
provide a visible clue to the "scope" of a "block" of statements. All
four of these statements are part of the case '-' "block and should be
indented at the same level/
case ',':
contFlag = 0;
list++;
break;
default:
field = 0;
while (*list >= '0' && *list <= '9')
{
field *= 10;
field += *list - '0';
++list;
}
if (field == 0) return(1);
else if (field > MAX_FIELD_SIZE) return(2);
--field; /* decrement field # for array index */
if (!contFlag) prevField = field;
else contFlag = 0;
while (prevField <= field)

This is an even worse example. The while statement is not part of the
range of the else. Your indenting makes it appear as if the while is
only executed when the if is false.
{
field_list[prevField++] = 1;
}
setFieldFlag = 1; /* set field selected flag
*/
} /* end switch */
} /* end while */

if (contFlag)
{
while (prevField <= MAX_FIELD_SIZE)
{
field_list[prevField++] = 1;

This invokes undefined behavior when prevField equals MAX_FIELD_SIZE.
The highest allowed index for field_list is MAX_FIELD_SIZE-1. You
probably want <, not <=, in the preceding while statement.
 
H

Hans Vlems

Due to I try using C.
I can't even figure out how many words you left out of that sentence.
Possibly none when translated back to the OP's native language <g>
Hans
 
M

moonhkt

Possibly none when translated back to the OP's native language <g>
Hans

And yet, for all that, it is perfectly clear what he meant.

--
Faced with the choice between changing one's mind and proving that there is
no need to do so, almost everyone gets busy on the proof.

    - John Kenneth Galbraith -[/QUOTE]


I found 'cut' source code in Internet, 'cut' using -c parameter. But I
can not understanding, how Set_list and set field_list[prevField++]
works. I try to add code to display field_list array. But, I still can
not understand. (I am not a C programmer, I am UNIX script Writer)
 
K

Keith Thompson

Hans Vlems said:
Possibly none when translated back to the OP's native language <g>
Hans

Hans, your newsreader should add attribution lines when you post
lines above. Please leave those lines in place. Knowing who said
what makes it easier to follow the discussion.
 

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,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top