Board index » cppbuilder » strange string pointer to strings...?

strange string pointer to strings...?


2005-09-29 01:44:19 AM
cppbuilder96
#include <stdio.h>
#include <conio.h>
#include <string.h>
int main(void)
{
/* this does not make sense to me that when i keep adding rows and columns
of strings to this array of pointers to strings it just keeps
going on, any explanation for this ?
*/
char *s[][5]= {
"one","qwer",
"two", "rewq",
"three", "qwer",
"four", "rewq",
"five", "qwertttt",
" ", " "
};
char **sp=0,w[10];
int c;
do
{
gets(w);
sp = (char **)s;//why r we supposed to init this pointer to pointer to
strings
// again and again thru the loop
do
{
if(!stricmp(*sp, w) ){
puts( *(sp+1) );// how this prints the right string in array
break;
}
if(!stricmp(*sp, w) )break;
sp+=2; // wat is this
}while(*sp);
c=getch();
}while(c != 'n');
getch();
return (0);
}
 
 

Re:strange string pointer to strings...?

"mujeebrm" <mujeebrm@y!.com>writes:
Quote
#include <stdio.h>
#include <conio.h>
#include <string.h>

int main(void)
{

/* this does not make sense to me that when i keep adding rows and columns
of strings to this array of pointers to strings it just keeps
going on, any explanation for this ?
The program is severely flawed in several ways. It suspiciously looks
like a school assignment, so I won't give you the solution.
Quote
*/
char *s[][5]= {
"one","qwer",
"two", "rewq",
"three", "qwer",
"four", "rewq",
"five", "qwertttt",
" ", " "
};
Please read the other post of today by myself in this group. It is a
bad idea to have pointers to char (non-const) pointing at string
literals.
Then 5 is obviously too short for "three" and "qwertttt".
Quote
char **sp=0,w[10];
int c;

do
{
gets(w);
A call to this function is *always* a bug. The function must
*absolutely never* be used, because it doesn't check the size of the
buffer.
Have a look at fgets() as a replacement.
Quote
sp = (char **)s;//why r we supposed to init this pointer to pointer to
strings
// again and again thru the loop
You can't have a pointer to pointer to char point to an array of
arrays of char. The types are not compatible. The endless loop in your
program is a consequence of this incompatibility.
 

Re:strange string pointer to strings...?

Dear Sir Thomas Maedar,
i am not in a school. I am learning to program as a hobby thru c,c++. this
is not a school assignment. this program is taken from example code given in
a book which i could not understand and sought U peoples help in deciphering
this code.
plz help me in this regard. thanx
mujeebrm.
"Thomas Maeder [TeamB]" < XXXX@XXXXX.COM >wrote in
Quote
The program is severely flawed in several ways. It suspiciously looks
like a school assignment, so I won't give you the solution.
 

{smallsort}

Re:strange string pointer to strings...?

"mujeebrm" <mujeebrm@y!.com>writes:
Quote
i am not in a school. I am learning to program as a hobby thru
c,c++. this is not a school assignment.
Please note that there is no programming language called "C,C++". C
and C++ have become quite distinct languages, each with its own
idioms, best (and worst) practices etc.
Others may disagree here, but I think that you should either learn C
or C++, but not both at the same time.
Whichever you pick, make sure to have a look at the book reviews at
www.accu.org/ .
Quote
this program is taken from example code given in a book which i
could not understand and sought U peoples help in deciphering this
code.
Good. No program is bad enough to not work as a bad example. :-)
Quote
#include <stdio.h>
#include <conio.h>
#include <string.h>
Since you are learning, please note that <conio.h>(and the getch()
function probably declared in it) aren't part of the C nor the C++ ISO
Standard. I personally think that you would do better with a book that
sticks to the language standard.
Quote
int main(void)
{

/* this does not make sense to me that when i keep adding rows and columns
of strings to this array of pointers to strings it just keeps
going on, any explanation for this ?
*/
char *s[][5]= {
"one","qwer",
"two", "rewq",
"three", "qwer",
"four", "rewq",
"five", "qwertttt",
" ", " "
};
Yesterday, it didn't make sense to me either :-) My remark about 5
being too small was wrong.
It's a complex statement, defining a complex data structure and
initializing it in a rather obfuscated way.
First, you have to learn how to read declarators. The right way to
read them is to start at the name being declared (which isn't always
as obvious as here) and read outward, following operator
precedence. In this case, this means:
s is defined to be an array of a size determined by the initializer
which is part of the definition. The elements of s are arrays of 5
pointers to char.
The initializer is the part of the definition surrounded by curly
braces. In this particular case, s[0][0] is initialized with "one",
s[0][1] with "qwer" etc. s[0][4] is initialized with "three", s[1][0]
with "qwer" and so on. Since there are twelve string literals in the
initializer, the second " " initializes s[2][1]. s has thus 2
elements, and the remaining elements of s[2] are initialized to be
null pointers.
Please do look up declarators and initializers in a good text
book. This part of the C syntax is generally considered an experiment
that failed.
And let me repeat that it's a really bad idea to have a pointer to
non-const (such as s[0][0] point at a string literal). The type of s
should be
char const *s[2][5]
Quote
char **sp=0,w[10];
int c;
Having read the above-mentioned textbook chapters, what do these
statements mean?
Going on doesn't make any sense before you can answer this question.
 

Re:strange string pointer to strings...?

Hi Sir Thomas,
this is original code example which i had modified and posted from the book
C++ The Complete Reference,3rd ed. written by Herb Schildt.
thanx
mujeeb.
/* A simple dictionary. */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
/* list of words and meanings */
char *dic[][40] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
"", "" /* null terminate the list */
};
int main(void)
{
char word[80], ch;
char **p;
do {
puts("\nEnter word: ");
scanf("%s", word);
p = (char **)dic;
/* find matching word and print its meaning */
do {
if(!strcmp(*p, word)) {
puts("Meaning:");
puts(*(p+1));
break;
}
if(!strcmp(*p, word)) break;
p = p + 2; /* advance through the list */
} while(*p);
if(!*p) puts("Word not in dictionary.");
printf("Another? (y/n): ");
scanf(" %c%*c", &ch);
} while(toupper(ch) != 'N');
return 0;
}
"Thomas Maeder [TeamB]" < XXXX@XXXXX.COM >wrote in
Quote

>char **sp=0,w[10];
>int c;

Having read the above-mentioned textbook chapters, what do these
statements mean?

Going on doesn't make any sense before you can answer this question.
 

Re:strange string pointer to strings...?

mujeebrm wrote:
Quote
/* list of words and meanings */
char *dic[][40] = {
"atlas", "A volume of maps.",
This would more properly be written
char *dic[] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
0,0 /* null terminate the list */
};
 

Re:strange string pointer to strings...?

Bob Gonder < XXXX@XXXXX.COM >writes:
Quote
>/* list of words and meanings */
>char *dic[][40] = {
>"atlas", "A volume of maps.",

This would more properly be written

char *dic[] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",

0,0 /* null terminate the list */
};
Better yet
char const *dic[][40] = {
etc.
 

Re:strange string pointer to strings...?

"mujeebrm" <mujeebrm@y!.com>writes:
Quote
this is original code example which i had modified and posted from
the book C++ The Complete Reference,3rd ed. written by Herb Schildt.
I suspected that. This author is notorious for the lack of quality of
his books.
Quote
int main(void)
{
char word[80], ch;
char **p;

do {
puts("\nEnter word: ");
scanf("%s", word);
This is just as bad as using gets(). If the character sequence in the
input buffer is too long, the of word will be overrun. The *scanf()
functions allow the maximum number of input characters to be specified
for each conversion; e.g. "%79s".
Also, scanf() returns a value indicating success of the input
operation. It is wrong not to check that value.
Quote
p = (char **)dic;
This cast is a recipe for disaster. Because the program is lying to
the compiler.
If the type of dic is changed to
char const *dic[] = ...
and that of p to
char const **p;
then the assignment
p = dic;
compiles without the cast. And the program has a chance to work
correctly.
Quote

/* find matching word and print its meaning */
do {
if(!strcmp(*p, word)) {
puts("Meaning:");
puts(*(p+1));
break;
}
if(!strcmp(*p, word)) break;
This line is completely superfluous.
Quote
p = p + 2; /* advance through the list */
} while(*p);
if(!*p) puts("Word not in dictionary.");
printf("Another? (y/n): ");
scanf(" %c%*c", &ch);
Another ignored return value ...
 

Re:strange string pointer to strings...?

Thomas Maeder [TeamB] wrote:
Quote
>/* find matching word and print its meaning */
>do {
>if(!strcmp(*p, word)) {
>puts("Meaning:");
>puts(*(p+1));
>break;
>}
>if(!strcmp(*p, word)) break;

This line is completely superfluous.
Not so... It terminates the program after finding one word.
 

Re:strange string pointer to strings...?

Thomas Maeder [TeamB] wrote:
Quote
Bob Gonder writes:

>>/* list of words and meanings */
>>char *dic[][40] = {
>>"atlas", "A volume of maps.",
>
>This would more properly be written
>
>char *dic[] = {
>"atlas", "A volume of maps.",
>"car", "A motorized vehicle.",
>"telephone", "A communication device.",
>"airplane", "A flying machine.",
>
>0,0 /* null terminate the list */
>};

Better yet

char const *dic[][40] = {
Now, see... that looks a lot like a two dimensional array of pointers
to me.
Perhaps
typedef struct{char entry[40];} dic_entry;
dic_entry const * dic[] = {
If you want a literal array, just
const char dic[][40] = {
A one-dimensional array of [40 char] entities.
In fact, I just compiled this and set the dump view of debug to dic,
and saw a whole bunch of zeros between dic2 and dic3 (about 30
pointer's worth). The only zeros between dic and dic2 are the nulls.
typedef struct{char entry[40];} dic_entry;
/* An array of 10 pointers */
dic_entry*dic[] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
0,0};
/* An array of 10 pointers */
char const *dic1[] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
0,0};
/* One array of 40 pointers, zero-filled */
char const*dic2[][40] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
0,0};
/* so we can see the end of the array */
char const*dic3[] = {1,2,3,4};
/* 10 asciz strings ocupying 40 bytes each */
char const dic5[][40] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
0,0};
 

Re:strange string pointer to strings...?

Bob Gonder < XXXX@XXXXX.COM >writes:
Quote
>>/* find matching word and print its meaning */
>>do {
>>if(!strcmp(*p, word)) {
>>puts("Meaning:");
>>puts(*(p+1));
>>break;
>>}
>>if(!strcmp(*p, word)) break;
>
>This line is completely superfluous.

Not so... It terminates the program after finding one word.
Doesn't the break statement in the first if block already do that?
 

Re:strange string pointer to strings...?

Bob Gonder < XXXX@XXXXX.COM >writes:
Quote
Thomas Maeder [TeamB] wrote:

>Bob Gonder writes:
>
>>>/* list of words and meanings */
>>>char *dic[][40] = {
>>>"atlas", "A volume of maps.",
>>
>>This would more properly be written
>>
>>char *dic[] = {
>>"atlas", "A volume of maps.",
>>"car", "A motorized vehicle.",
>>"telephone", "A communication device.",
>>"airplane", "A flying machine.",
>>
>>0,0 /* null terminate the list */
>>};
>
>Better yet
>
>char const *dic[][40] = {

Now, see... that looks a lot like a two dimensional array of pointers
to me.
I meant to only add const to your suggestion; but I didn't.
The correct definition of dic is
char const *dic[] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
0,0 /* null terminate the list */
};
It's simply a bad idea to let a pointer to non-const point at objects
that must not be modified.
 

Re:strange string pointer to strings...?

Thomas Maeder [TeamB] wrote:
Quote
>>>/* find matching word and print its meaning */
>>>do {
>>>if(!strcmp(*p, word)) {
>>>puts("Meaning:");
>>>puts(*(p+1));
>>>break;
>>>}
>>>if(!strcmp(*p, word)) break;
>>
>>This line is completely superfluous.
>
>Not so... It terminates the program after finding one word.

Doesn't the break statement in the first if block already do that?
Oh, wait, you're right. That crazy formatting threw me.
I was thinking it was outside the inner loop.