string query

P

ptq2238

Hi, I've been experimenting further to understand about ordering
strings.
I had changed the code which tested ordered a list of char ( which
worked ) to string
but it's not giving the results I was expected. I was expecting to
have the strings in an increasing order.

Now, I'm getting confused and would appreciate if someone can explain
why I'm getting these results is greatly appreciated. Am I going about
this the correct way ?

struct testRec
{
char name[5];
struct testRec *nextrec;
};

typedef struct testRec records;
typedef records *recordptr;

void addName(recordptr *start, char *item);

int main ()
{
recordptr start = NULL;
char item[5];
.......
gets(item);
addRec(&start, item);
.....
return 0;
}

void addRec(recordptr *start, char *item)
{
recordptr newptr, prevptr, thisptr;
newptr = malloc(sizeof(records));

if(newptr != NULL)
{
strcpy(newptr->name, item);
newptr->nextrec = NULL;

prevptr = NULL;
thisptr = *start;

while (thisptr != NULL)
{
if (item > thisptr->name)
{
prevptr = thisptr;
thisptr = thisptr->nextrec;
}
}
if (prevptr == NULL)
{
newptr->nextrec = *start;
*start = newptr;
}
else
{
prevptr->nextrec = newptr;
newptr->nextrec = thisptr;
}
}
}

My output comes as
Enter a record :aa
List is : aa ->
Enter a record : dd
List is : aa -> dd ->
Enter a record : cc
List is :aa -> dd -> cc ->
Enter a record : bb
List is :aa -> dd -> cc -> bd ->
 
R

Richard Heathfield

(e-mail address removed) said:

My output comes as
Enter a record :aa
List is : aa ->
Enter a record : dd
List is : aa -> dd ->
Enter a record : cc
List is :aa -> dd -> cc ->
Enter a record : bb
List is :aa -> dd -> cc -> bd ->

How strange. My output comes as:

foo.c:13: warning: function declaration isn't a prototype
foo.c: In function `main':
foo.c:14: `NULL' undeclared (first use in this function)
foo.c:14: (Each undeclared identifier is reported only once
foo.c:14: for each function it appears in.)
foo.c:16: parse error before `...'
foo.c:18: warning: implicit declaration of function `addRec'
foo.c:19: parse error before `...'
foo.c:21: warning: control reaches end of non-void function
foo.c: At top level:
foo.c:24: warning: no previous prototype for `addRec'
foo.c:24: warning: type mismatch with previous implicit declaration
foo.c:18: warning: previous implicit declaration of `addRec'
foo.c:24: warning: `addRec' was previously implicitly declared to return
`int'
foo.c: In function `addRec':
foo.c:26: warning: implicit declaration of function `malloc'
foo.c:26: warning: assignment makes pointer from integer without a cast
foo.c:28: `NULL' undeclared (first use in this function)


Perhaps it would be better to post the code you're actually using.
 
C

Chris Dollin

(e-mail address removed) wrote:

(fx:snip)
void addRec(recordptr *start, char *item)
(fx:snip)

if (item > thisptr->name)

Comparisons of pointers (`item` and `thisptr->name` are both
`char*`) isn't comparison of strings. What's more, here it's
Undefined Behaviour [1].

(fx:announcer) Mr strcmp is trying to friend you ...

[1] Run away! Run away!
 
L

Lew Pitcher

Hi, I've been experimenting further to understand about ordering
strings.
I had changed the code which tested ordered a list of char ( which
worked ) to string
but it's not giving the results I was expected. I was expecting to
have the strings in an increasing order.

Now, I'm getting confused and would appreciate if someone can explain
why I'm getting these results is greatly appreciated. Am I going about
this the correct way ?

struct testRec
{
char name[5];
struct testRec *nextrec;

};

typedef struct testRec records;
typedef records *recordptr;
[snip]
void addRec(recordptr *start, char *item)
{
recordptr newptr, prevptr, thisptr;
newptr = malloc(sizeof(records));

if(newptr != NULL)
{ [snip]
while (thisptr != NULL)
{
if (item > thisptr->name)

Richard's comments notwithstanding, you have a problem in the test
above.

Think of what you are comparing:
item is a pointer
thisptr->name is a string (which, for the purposes of this
comparison can be considered to be a pointer)
Is it your goal to determine if one pointer is numerically greater
than another? Rather, are you not concerned about the relationship
between the strings pointed to by each pointer?

Rewrite this if statement so that it compares the strings, not the
pointers. And, of course, make certain that you provide (or cause to
be provided) the prototype for any function that you use to perform
that string comparison.
[snip]

HTH
 
K

Keith Thompson

Hi, I've been experimenting further to understand about ordering
strings.
I had changed the code which tested ordered a list of char ( which
worked ) to string
but it's not giving the results I was expected. I was expecting to
have the strings in an increasing order.

Now, I'm getting confused and would appreciate if someone can explain
why I'm getting these results is greatly appreciated. Am I going about
this the correct way ?

I'm going to comment on your code without actually answering your
underlying question. Your code has a number of problems that you
should fix before you start worrying about why it behaves the way it
does.
struct testRec
{
char name[5];
struct testRec *nextrec;
};

typedef struct testRec records;
typedef records *recordptr;

The use of typedefs for structures is almost always unnecessary. A
lot of programmers do prefer to use typedefs for structure types, I
suppose just to give the structure a one-word name; you can do that if
you like, but it really doesn't accomplish anything. Typedefs for
pointer types, on the other hand, just cause confusion.

I would simply declare the structure type and drop the typedefs. If I
want to refer to the structure type, I'd just refer to
"struct testRec"; if I wanted to refer to a pointer to that type, I's
refer to "struct testRec*".

And why do you call the type "records" when it's a single record?

But if you insist on using a typedef, there's no reason to use a
different name than the one you used for the structure. For example:

typedef struct testRec
{
...
} testRec;

Now you can refer to your type as either "struct testRec" or
"testRec", and to the pointer type as "testRec*".
void addName(recordptr *start, char *item);

Your start parameter is a pointer to a pointer. If you had declared
it as "struct testRec **start" or "testRec **start", that would have
been clearer.
int main ()

"int main(void)" is preferred.
{
recordptr start = NULL;
char item[5];
......
gets(item);

Never use gets(). Think about what happens if I type a long line, and
read question 12.23 in the comp.lang.c FAQ, <http://www.c-faq.com/>.

[snip]

Furthermore, the program you posted is incomplete. You're missing
several required #include directives, and you have "......" in a
couple of places. We can help you much better if you post a complete,
compilable program that illustrates whatever problem you're having.
 
R

Richard Tobin

Consider comparing strings with strcmp (in <strings.h>).
[/QUOTE]
Huh? Since when?

Early 1980s. Perhaps you should have asked "until when?", to which
the answer is arguably 1989.

7th edition unix had strcmp(), strcpy(), strlen(), index() etc, but
didn't have either <string.h> or <strings.h> - presumably you were
supposed to declare the ones that didn't return int yourself, though
it didn't matter since int and char * were the same size.

BSD (probably 4.1, I don't have the manual handy to check) introduced
<strings.h> to declare these. Some early System V introduced
<string.h> for the same purpose. Somewhere along the way System V
presumably also renamed index() and rindex(). And it was the System V
versions that were adopted by the ANSI standard.

-- Richard
 
B

Barry Schwarz

Huh? Since when?

Early 1980s. Perhaps you should have asked "until when?", to which
the answer is arguably 1989.[/QUOTE]

There is no standard header called strings.h, not in K&R II, not in
C89, and not in C99. I assume RH didn't feel the need for a smiley
for something so obvious.
7th edition unix had strcmp(), strcpy(), strlen(), index() etc, but
didn't have either <string.h> or <strings.h> - presumably you were

I didn't realize unix was a compiler but its variations from the
standard are also irrelevant, at least in this group.
supposed to declare the ones that didn't return int yourself, though
it didn't matter since int and char * were the same size.

It certainly does matter. Having the same size is convenient. Having
the correct type is mandatory. Think of code like
strcat(strcpy(large_array_of_char,"abcdef"),"123456");
BSD (probably 4.1, I don't have the manual handy to check) introduced
<strings.h> to declare these. Some early System V introduced
<string.h> for the same purpose. Somewhere along the way System V
presumably also renamed index() and rindex(). And it was the System V
versions that were adopted by the ANSI standard.


Remove del for email
 
C

Charles Richmond

Richard said:
CBFalconer said:



Huh? Since when?

Yeah, I always have to think twice when using <string.h>
that I don't type <strings.h>. (I have used BSD systems
that had <strings.h> in the distant past.)
 
R

Richard Tobin

Early 1980s. Perhaps you should have asked "until when?", to which
the answer is arguably 1989.

There is no standard header called strings.h, not in K&R II, not in
C89, and not in C99.[/QUOTE]

And which of them was published before 1989?
I didn't realize unix was a compiler but its variations from the
standard are also irrelevant, at least in this group.

Where do you think the C standard came from? Out of thin air?
If you want to know why C is the way it is, you need to understand
its unix history. If you think that's off-topic for this group,
tough.
It certainly does matter.

Are you incapable of understanding that a comment might be about a
particular historical system? Hint: note the use of the past tense.
Having the same size is convenient. Having
the correct type is mandatory. Think of code like
strcat(strcpy(large_array_of_char,"abcdef"),"123456");

What is your point? You can take that question either generally or
specifically.

-- Richard
 

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,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top