Find value of some key

I

Ian Collins

if i have to criticize this code
this not compile here

Error E2188 b.c 36: Expression syntax in function print_table
Error E2451 b.c 36: Undefined symbol 'i' in function print_table
Error E2379 b.c 36: Statement missing ; in function print_table
Warning W8057 b.c 40: Parameter 'f' is never used in function print_table
Warning W8057 b.c 40: Parameter 'v' is never used in function print_table
Error E2188 b.c 46: Expression syntax in function get_value
Error E2451 b.c 46: Undefined symbol 'i' in function get_value
Error E2379 b.c 46: Statement missing ; in function get_value
Warning W8057 b.c 60: Parameter 'f' is never used in function get_value
Warning W8057 b.c 60: Parameter 'v' is never used in function get_value
*** 6 errors in Compile ***

even if use C99, there is always one error
__func__ has be __FUNC__ here

Get a decent compiler.
 
I

Ike Naar

Vincenzo Mercuri said:
int main(void){


const char* fields[] = {"OS",
"compiler",
"text-editor",
"mentor", NULL};

Please forgive me for the digression, but here is a brace style issue
that has often puzzled me.
Some people write (A)

header
{
body
}

Other people write (B)

header {
body
}

The nice thing about (A) is that the braces line up neatly.
The nice thing about (B) is that it saves vertical space, compared to (A).

But this (C)

header {

body
}

seems to be the worst of both worlds; neither do the braces line up,
nor does it save vertical space.
What would be the rationale for brace style (C) ?
 
A

arnuld

The fundamental approach is bad.

I may agree on this.


Make a skiplist and you can have a generic, ordered container. Or make
a hash table and you will have ultra-fast equality searching.

So the first part of the problem is to clearly specify the problem. Once
the problem is set in stone and all the parameters are clearly known,
then the rest of the system falls out all by itself.


Well, the basic issue is that I receive data on some socket() which is
saved into a char array which looks like this:


Name: MY_PHONE
Core-ID: fb6b20fa-fabe-467c-8ec9-0edc1e335497

Machine-Hostname: gnu
Machine-IPv4: 192.168.0.202

Caller-Name: arnuld
Caller-ID: System_Programmer
Caller-Status: Call_Failed


I have to find some value in that array belonging to a key, just once,
well, may be twice in a rare situation. I did not talk about socket fd
here as its not the place to talk about those things. So I have find the
the values in a char array belonging to one or two unique key. This is
all I have to do.


But Dan, I did get some programming ideas from you (loved reading
them :) )
 
A

arnuld

Yes. In fact, the mere name "arnuld" conjurs up these impressions:

(1) not very experienced;
(2) willing and (unlike BC) able to learn;
(3) friendly, personable;
(4) doesn't suffer from Mohammed Ali Syndrome.

Oh .. Richard, I am obliged to you for your gracious hospitality :)
 
M

Mark Bluemel

Well, the basic issue is that I receive  data on some socket() which is
saved into a char array which looks like this:

Name: MY_PHONE
Core-ID: fb6b20fa-fabe-467c-8ec9-0edc1e335497

Machine-Hostname: gnu
Machine-IPv4: 192.168.0.202

Caller-Name: arnuld
Caller-ID:   System_Programmer
Caller-Status: Call_Failed

Taking about keys and arrays is somewhat misleading, IMHO.

To my mind each record received consists of a (fixed?) number of lines
each of which is made up of two fields (key and value), separated by a
':' followed by an arbitrary amount of whitespace.

If you have to do a lot of processing with the data, it may be worth
parsing each blob into an array of { char *key; char *value} structs.
With a small number of records, simple linear searching of the array
is probably all that is needed.

If you only need to look at the values associated with one or two
keys, then looking for a key followed by a ':' _at the beginning of a
line_ is probably sufficient.
 
V

Vincenzo Mercuri

Il 24/06/2010 09:22, io_x ha scritto:
Vincenzo Mercuri said:
Il 23/06/2010 21.46, io_x ha scritto:

...is that a joke? Why this behaviour?

all your post in this argument, all togheter are a joke
*or* i not understand them

the OP problem
has to be seen using structs, array of structs, or table of structs
etc, or i not understand what OP whant

this is one useful example

#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>

#define W while
#define R return
#define F for
#define P printf
#define B break

typedef struct{
char Os[128];
char editor[128];
char mentor[128];
}element;

// k==0 means search OS
// k==1 search editor
// k==2 means search mentor
// find from "start".."end" "whatSearch" in the array of struct "where"
int
findNext(element* where, int start, int end, char* whatSearch, int k)
{int i, j;
char *pc;

if(where==0||whatSearch==0||start>end)
R -1;
if(k==0) k=offsetof(element, Os);
else if(k==1) k=offsetof(element, editor);
else if(k==2) k=offsetof(element, mentor);
else R -1;

F(i=start; i<=end; ++i)
{F(j=0; ; ++j)
{if(where.Os[j+k]==whatSearch[j])
{if(whatSearch[j]==0)
R i;
}
else break;
}
}
R -1;
}

int findNextOs (element* w, int start, int end, char* search)
{R findNext(w, start, end, search, 0);}

int findNextEditor(element* w, int start, int end, char* search)
{R findNext(w, start, end, search, 1);}

int findNextMentor(element* w, int start, int end, char* search)
{R findNext(w, start, end, search, 2);}


int insert(element* w, int pos, element* v)
{int i;
if(w==0||v==0) R 0;
F(i=0; i<(int) sizeof(element); ++i)
w[pos].Os=(*v).Os;
R 1;
}

int def(element* v, char* Os, char* editor, char* mentor)
{int i;

if(v==0||Os==0||editor==0||mentor==0) R 0;
i=0;
W(1){v->Os=Os;
if(Os==0) B;
if(i>=127) R 0;
++i;
}

i=0;
W(1){v->editor=editor;
if(editor==0) B;
if(i>=127) R 0;
++i;
}

i=0;
W(1){v->mentor=mentor;
if(mentor==0) B;
if(i>=127) R 0;
++i;
}

R 1;
}

int showElement(element* t)
{if(t==0||t->Os==0||t->editor==0||t->mentor==0)
R 0;
P("Os : %s\n", t->Os);
P("editor: %s\n", t->editor);
P("mentor: %s\n", t->mentor);
R 1;
}

int showTable(element* t, int num)
{int i;
if(t==0) R 0;
F(i=0; i<num; ++i)
{P("Element %d\n", i);
showElement(t+i);
P("\n");
}
R 1;
}

int azzeraTable(element* where, int number)
{int i;
if(where==0) R 0;
F(i=0; i<number; ++i){where.Os [0]=0;
where.editor[0]=0;
where.mentor[0]=0;
}
R 1;
}

int main(void)
{int i;
char arr[512], *p1, *p2, *p3;
element table[1024]; // one general table of 1024 elements


azzeraTable(table, 1024);
F(i=0; i<512; ++i) arr=0;

p1=arr+ 0;
p2=arr+128;
p3=arr+256;

F(i=0; i<100; ++i)
{sprintf(p1, "%.91s%d", "XOs", i);
sprintf(p2, "%.91s%d", "Xeditor", i);
sprintf(p3, "%.91s%d", "Xmentor", i);
def(table+i, p1, p2, p3);
}
def(table+203, "XOs23", "Xeditor23", "Xmentor23");
showTable(table, 100);
showElement(table+203);

F(i=0; ;)
{i=findNextOs(table, i, 1023, "XOs23");
if(i!=-1) P("Find XOs23 in struct %d\n", i);
else B;
++i;
}

F(i=0; ;)
{i=findNextEditor(table, i, 1023, "Xeditor23");
if(i!=-1) P("Find Xeditor23 in struct %d\n", i);
else B;
++i;
}

F(i=0; ;)
{i=findNextMentor(table, i, 1023, "Xmentor23");
if(i!=-1) P("Find XMentor23 in struct %d\n", i);
else B;
++i;
}

R 0;
}


what beutiful peace of code :)
I think we all appreciate to get fun with code sometimes, but why
this try to prove yourself as some kind of a bizarre genius?

all we are genius because each of we can write something nobody
can write
If this is your intent, you are unlikely able to do it.

were i'm unlike
I think there are some people here who would really have
enough skills to do better.

yes i know it too, but in this tread they not write well, i not understand
If they only wanted.
yes

So, even as a joke it is not well-made. We are all free to
use the style we prefer,

so i use my
yes my error could be this, if each of us use his/her style
it is possible no one understand what the other write

but i'm not for this interpretation, i can read well all code
is here, even the strange one, if think about it 10 minuts
and debug something
but i think sometimes you persist
in showing off a bit of lack of regards about the readers.

yes, but i'm not OT, the code above is 100% standard C
so i could post it
but some day i will be tired, and will go away
Trying to be clear and showing our ideas in an intelligible manner
would be desirable by the most (hopefully).
And about your italian words in your code...I am italian too,

i find only one half italian word in that code "azzeraTable".
you find more thant one word?
but i think it is easily understandable in english
exist "zero" too
and i think i have to recall you that english is the lingua franca
in programming, and we should use it when talking to people overseas,

i'm not agree, something can be written in own language too
so we can all understand, appreciate and share new ideas.
Please don't continue with this self-destructive behaviour,

this is not self-destructive behaviour
and try to let people appreciate your true abilities.

thanks for this line


ok, you are even free to be left alone.

All the best
 
B

BruceS

On Jun 23, 11:55 am, Vincenzo Mercuri <[email protected]>
wrote:
and i think i have to recall you that english is the lingua franca
in programming, and we should use it when talking to people overseas, so

When I was teaching, I would tell the students "English is the de
facto lingua franca of the Internet." I thought it was pretty funny,
but it seemed to fly right by most of the students.
FWIW, I've read C written by Poles, French, Russians, Chinese, and
others, and found that good code was still easy to follow. Sure,
having identifiers and comments in one's own language is helpful, but
I'd rather read well-structured code where the names are (to me)
unrelated to purpose than the all-too-common code where the names
mislead.
I almost added a closing little joke, but decided against, as I've
previously overestimated clc regulars' humor quotient.
 
V

Vincenzo Mercuri

Il 24/06/2010 16:41, BruceS ha scritto:
On Jun 23, 11:55 am, Vincenzo Mercuri<[email protected]>
wrote:

having identifiers and comments in one's own language is helpful, but
I'd rather read well-structured code where the names are (to me)
unrelated to purpose than the all-too-common code where the names
mislead.
<snip>

I definitely agree with you. But this is not the case.
What I meant was to point out the intentions in using
one's own language. If the purpose is to intentionally
make your reading harder, then i think it is not the right
place to do that, because a newsgroup is supposed (i hope)
to provide readable news for the most (of C programmers, in this case),
if not, the word 'news' loses its whole meaning and it becomes a
'note' just for the writer himself, no more a group.
There exists the newsgroup it.comp.lang.c for italian people who want to
use the italian language. I didn't mean to do a mere exaltation
of one language against another one. Far from me that purpose.
As I said i'm italian and i know it would make me happier
having the same articles entirely available in my own language.
It's a mere question of regard for the person you are talking to.
My little criticism against that guy comes from having
read other articles he posted in the past.

I hope I made the reasons of my reaction clear.

Regards
 
K

Keith Thompson

BruceS said:
I almost added a closing little joke, but decided against, as I've
previously overestimated clc regulars' humor quotient.

Are you calling us humorless? That's not funny!

(I don't really need a smiley here, do I?)
 
I

iC and iC++

Which in turn should have also been....

Forget it. I'm going back to talking to myself.

My grammar skills and learning abilities are besides the point in this
case and have no bearing on why I was vexed at your petty insults
concerning either. Plus, i thought i you 'kill-filed' me.

Indeed, I was the one trying to learn about pointers from a book that
I was told not to use. I kept reading it because not only do I always
finish what i start, I even learned some common source of errors that
can potentially plague new programmers like me, so I can look out for
them. If I said anything to offend you sir, it was because I noticed
that one of you favorite activities was to belittle people who you
feel are less average than you for whatever reason than you can find.
You even did it to arnuld. What Eric said to you is exactly the
message I wanted to convey with my retort in my post about pointers.
Anyways, I do not wish to contend with you any longer and I am sure
that you don't enjoy it, so with this, we should let it go.
 
V

Vincenzo Mercuri

Ike said:
Vincenzo Mercuri said:
int main(void){


const char* fields[] = {"OS",
"compiler",
"text-editor",
"mentor", NULL};

Please forgive me for the digression, but here is a brace style issue
that has often puzzled me.
Some people write (A)

header
{
body
}

Other people write (B)

header {
body
}

The nice thing about (A) is that the braces line up neatly.
The nice thing about (B) is that it saves vertical space, compared to (A).

But this (C)

header {

body
}

seems to be the worst of both worlds; neither do the braces line up,
nor does it save vertical space.
What would be the rationale for brace style (C) ?

Ok, i think i have to better understand how thunderbird
and seamonkey work, because i have some issues when i copy
and paste my code from Gedit or other editors.
In my editor formatting looks like the (B) option.
i'll do my best to fix formatting issues.
 
V

Vincenzo Mercuri

Vincenzo said:
Ike said:
Vincenzo Mercuri said:
int main(void){


const char* fields[] = {"OS",
"compiler",
"text-editor",
"mentor", NULL};

Please forgive me for the digression, but here is a brace style issue
that has often puzzled me.
Some people write (A)

header
{
body
}

Other people write (B)

header {
body
}

The nice thing about (A) is that the braces line up neatly.
The nice thing about (B) is that it saves vertical space, compared to
(A).

But this (C)

header {

body
}

seems to be the worst of both worlds; neither do the braces line up,
nor does it save vertical space.
What would be the rationale for brace style (C) ?

Ok, i think i have to better understand how thunderbird
and seamonkey work, because i have some issues when i copy
and paste my code from Gedit or other editors.
In my editor formatting looks like the (B) option.
i'll do my best to fix formatting issues.

I think there is no rationale though.
The best is what you prefer, but you are supposed
to use the same style everywhere in your code.
Anyway some editors have a 'code beautifier'
which formats your lines in the GNU, or Linux, or K&R,
-like style. You may also want to use the 'indent'
command-line (gnu-)tool:

http://www.gnu.org/software/indent/

Cheers
 
V

Vincenzo Mercuri

Il 24/06/2010 15.10, arnuld ha scritto:
I may agree on this.





Well, the basic issue is that I receive data on some socket() which is
saved into a char array which looks like this:


Name: MY_PHONE
Core-ID: fb6b20fa-fabe-467c-8ec9-0edc1e335497

Machine-Hostname: gnu
Machine-IPv4: 192.168.0.202

Caller-Name: arnuld
Caller-ID: System_Programmer
Caller-Status: Call_Failed


I have to find some value in that array belonging to a key, just once,
well, may be twice in a rare situation. I did not talk about socket fd
here as its not the place to talk about those things. So I have find the
the values in a char array belonging to one or two unique key. This is
all I have to do.


But Dan, I did get some programming ideas from you (loved reading
them :) )

Ok, now i think i got what the problem is.
Usually you receive data from a socket file descriptor
through a function whose prototype looks like this:

receive(..., void* buffer, size_t n, ...);

that relies on a buffer to write n bytes of data.
Let's say you receive those bytes in a readable format,
i.e. a string. All you have to do is to tokenize that string. How?
I would use the strtok function (while declared 'deprecated'
on some implementation: 'strtok_s' is preferred) from the Standard
Library, whose prototype (C99) is:

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

see for example:
http://www.cplusplus.com/reference/clibrary/cstring/strtok/

We have just to pass to s2 a string of characters we want to discard
in our search; this will permit us to 'tokenize' a long string.

Let's also say that we want the keys of our search to be passed
as command-line arguments to our executable, so that we will be able
to start our search by typing for example: ./valueof [key(s)]

Then, let's try:

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

/* I assume that lines like "Machine-Hostname: gnu" and
"Machine-IPv4: 192.168.0.202" may be separated
by \r or \n or both */
#define END_OF_LINE "\r\n"

/* I intend to get the words (strings) "Name" and "MY_PHONE"
from a line like "Name: MY_PHONE" */
#define WORD_SEPARATOR " :"

#define BUFFER_SIZE 1024

/* by 'line' I mean a string like "Name: MY_PHONE"
without any newline or carriage return.

ps: I assume there could be white spaces before or
between the comma and the words
(eg. the case "Name : MY_PHONE") */
#define NUMBER_OF_LINES 100

/* by 'field' I mean a word like "Name" in "Name: MY_PHONE"
or "Machine-Hostname" in "Machine-Hostname: gnu" */
#define NUMBER_OF_FIELDS 100

/* by 'value' I mean a word like "MY_PHONE" in "Name: MY_PHONE"
or... */
#define NUMBER_OF_VALUES 100

char* get_value(char* f[], char* v[], char* k);

/* just to allow this code to work, we assume to already
have the string received from the socket, in the same form
as *arnuld* gave us (I will just insert some random \r at the
end of a line or a white space between words and comma):

Name: MY_PHONE
Core-ID: fb6b20fa-fabe-467c-8ec9-0edc1e335497

Machine-Hostname: gnu
Machine-IPv4: 192.168.0.202

Caller-Name: arnuld
Caller-ID: System_Programmer
Caller-Status: Call_Failed */

int main(int argc, char* argv[])
{

char buffer[BUFFER_SIZE];

char* lines[NUMBER_OF_LINES] = { NULL };

char* fields[NUMBER_OF_FIELDS] = { NULL };
char* values[NUMBER_OF_VALUES] = { NULL };

/* ...code for receiving data from socket_fd to buffer...so
the next call to strcpy is just to make our code work */

strcpy(buffer, "Name : MY_PHONE \n"
"Core-ID: fb6b20fa-fabe-467c-8ec9-0edc1e335497 \r\n\n"
"Machine-Hostname: gnu \n\r"
"Machine-IPv4: 192.168.0.202 \n\n"
"Caller-Name: arnuld \n\r\r"
"Caller-ID : System_Programmer \n"
"Caller-Status: Call_Failed \n");

printf("\n");

if (( lines[0] = strtok(buffer, END_OF_LINE) )) {
for(int i = 1; ( lines = strtok(NULL, END_OF_LINE) ); i++);

} else {
printf("No data received.\n");
return 1;
}

for(int i = 0; lines; i++) {
fields = strtok(lines, WORD_SEPARATOR);
if (( !(values = strtok(NULL, WORD_SEPARATOR)) ))
values = ""; /* if a field is not given a value */
}

if (argc > 1) {
for(int i = 1; i < argc; i++)
get_value(fields, values, argv);
} else {
printf("Usage: %s [key(s)]\n\n", argv[0]);
return 0;
}

printf("\n");
return 0;
}

char* get_value(char* f[], char* v[], char* k)
{
int found = 0;

for(int i = 0; f; i++) {
if ( !strcmp(f, k) ) {
printf("%s = %s\n", f, v);
found = 1;
break;
}
}

if ( !found )
printf("No match for \"%s\"\n", k);

return found ? k : NULL ;
}

--------------------------------------------------------------

$ gcc -std=c99 main.c -o valueof
$ ./valueof Core-ID Machine-Hostname Caller-Status Elephant

Core-ID = fb6b20fa-fabe-467c-8ec9-0edc1e335497
Machine-Hostname = gnu
Caller-Status = Call_Failed
No match for "Elephant"



Regards
 
V

Vincenzo Mercuri

Il 25/06/2010 11.50, Vincenzo Mercuri ha scritto:
Il 24/06/2010 15.10, arnuld ha scritto:

have the string received from the socket, in the same form
as *arnuld* gave us (I will just insert some random \r at the
end of a line or a white space between words and comma):
<snip>

i meant 'colon', not comma.
 
B

BruceS

[...]
I almost added a closing little joke, but decided against, as I've
previously overestimated clc regulars' humor quotient.

Are you calling us humorless?  That's not funny!

I guess we'll just have to see.
(I don't really need a smiley here, do I?)

Yes. Yes, you do.

I generally avoid smileys, but something just occurred to me.
Wouldn't it be a wonderful coding style, both improving readability
and impressing readers with one's skills, to replace the various
keywords and punctuation marks in C (apparently preferred by stuck-in-
the-mud fuddy duddies) with emoticons? After all, *this* is the real
purpose of the preprocessor. The only questions left are (1) what are
the most appropriate smileys to use to replace "if", "double", etc.,
and (2) how to correctly write the macros for this.
 
B

BruceS

On Jun 24, 10:10 am, Vincenzo Mercuri <[email protected]>
wrote:
I hope I made the reasons of my reaction clear.

Absolutely. I think we're entirely in agreement on the advisability
of writing legibly for the expected audience, and likely on other
topics.
 
T

Tim Harig

[...]
I almost added a closing little joke, but decided against, as I've
previously overestimated clc regulars' humor quotient.

Are you calling us humorless?  That's not funny!

I guess we'll just have to see.
(I don't really need a smiley here, do I?)

Yes. Yes, you do.

I generally avoid smileys, but something just occurred to me.
Wouldn't it be a wonderful coding style, both improving readability
and impressing readers with one's skills, to replace the various
keywords and punctuation marks in C (apparently preferred by stuck-in-
the-mud fuddy duddies) with emoticons? After all, *this* is the real
purpose of the preprocessor. The only questions left are (1) what are
the most appropriate smileys to use to replace "if", "double", etc.,
and (2) how to correctly write the macros for this.

Oh God, please revoke this message quickly. Somebody *will* do this.

There is already a standard for including emoticons to indicate IP packet
"mood":

http://tools.ietf.org/rfc/rfc5841.txt

and a programing language in LOLCAT lingo:

http://lolcode.com/specs/1.2

Yes, somebody will do this and *I* will end up having to maintain the code.
Joke indeed. Ha!
 
B

BruceS

[...]
I almost added a closing little joke, but decided against, as I've
previously overestimated clc regulars' humor quotient.
Are you calling us humorless?  That's not funny!
I guess we'll just have to see.
Yes.  Yes, you do.
I generally avoid smileys, but something just occurred to me.
Wouldn't it be a wonderful coding style, both improving readability
and impressing readers with one's skills, to replace the various
keywords and punctuation marks in C (apparently preferred by stuck-in-
the-mud fuddy duddies) with emoticons?  After all, *this* is the real
purpose of the preprocessor.  The only questions left are (1) what are
the most appropriate smileys to use to replace "if", "double", etc.,
and (2) how to correctly write the macros for this.

Oh God, please revoke this message quickly.  Somebody *will* do this.

There is already a standard for including emoticons to indicate IP packet
"mood":

       http://tools.ietf.org/rfc/rfc5841.txt

and a programing language in LOLCAT lingo:

       http://lolcode.com/specs/1.2

Yes, somebody will do this and *I* will end up having to maintain the code.
Joke indeed. Ha!

As long as they use the correct variable naming, indentation, and
brace style, no problem! At times I have a lot of spare time, and
could address such a pressing need, but sadly this is not one of those
times.
 
V

Vincenzo Mercuri

On 25/06/2010 09:20, Vincenzo Mercuri wrote:
#define NUMBER_OF_LINES 100

/* by 'field' I mean a word like "Name" in "Name: MY_PHONE"
or "Machine-Hostname" in "Machine-Hostname: gnu" */
#define NUMBER_OF_FIELDS 100

/* by 'value' I mean a word like "MY_PHONE" in "Name: MY_PHONE"
or... */
#define NUMBER_OF_VALUES 100
<snip>

here you could write:

#define NUMBER_OF_FIELDS NUMBER_OF_LINES
#define NUMBER_OF_VALUES NUMBER_OF_LINES

to highlight the dependence of fields and values on the lines,
line = "field: value";

char* lines[NUMBER_OF_LINES] = { NULL };
>
char* fields[NUMBER_OF_FIELDS] = { NULL };
char* values[NUMBER_OF_VALUES] = { NULL };
<snip>

Both fields and values will be extracted from lines;

for(int i = 1; ( lines = strtok(NULL, END_OF_LINE) ); i++);


<snip>

here, a bound check could be made to handle the case when
we reach the end of lines[] (even if you think it would be unlikely),
so that line should be replaced by the following code:

for(int i = 1; ( lines = strtok(NULL, END_OF_LINE) ); i++)
if (i == NUMBER_OF_LINES - 2) {
printf("Bound of lines[] reached.\n");
printf("More data available.\n");
break;
}

Of course, you should add other error checks to improve this scratch.
 

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

Forum statistics

Threads
474,085
Messages
2,570,597
Members
47,220
Latest member
AugustinaJ

Latest Threads

Top