help a beginner : code not working

B

bpascal123

Hi,

I'm learning and I entered twice the code below and it 's not working
with the same error messages.This code is a little above my
understanding of C however I'd like to understand the part that talks
about getting inputs into "unsized" char arrays of pointers.


/*This prg manages 10 character strings and sort the total of string
from a to z ...*/

#include <stdio.h> /* printf, gets */
#include <string.h> /* strlen, strcpy, strcmp */
#include <stdlib.h> /* malloc, free, exit */
#include <conio.h> /* getche */

int main(void)
{
char *list[10] ; /* 10 pointers array */
char *temp ; /* for sorting */
char buffer[128] ; /* input */
int i = 0 ; /* count strings */
int m, n, rep ; /* for control */

printf("\n\nINITIALISATION OF A SORTED LIST\n") ;
printf("Maximum 10 entries. Input order :\n") ;
printf("\tLast name, first name (country)\n\n") ;

do /* String entries */
{
printf("\nPerson %d (quit with \'0\'(zero) : ", i+1 ) ;

/* 1° the code first says \"0\" - i changed it to \'0\' - i'm not
sure */

gets(buffer) ;

if (strcmp(buffer, '0') ) /* same as above 1° */
{
if ((list = (char *) malloc(strlen(buffer) + 1)) == NULL) /* +1
because it takes '\0' fromlist */
{
printf("\nMemory full.\n");

if ( i > 0 )
{
printf("\nDisplay current listing ? (o/n) ") ;
rep = getche() ;
if (rep == 'o')
break ;
}
exit(1) ;
}

strcpy(list, buffer) ;

i++ ;
}
} while ( i < 10 && strcmp(buffer, '0') ) ; /* same as 1° */

/***Array sorting ***/

for ( m = i - 1 ; m > 0 ; m-- )

for ( n = 0 ; n < m ; n++ )

if ( strcomp(list, list[n+1]) > 0 )
{
temp = list ;
list = list[n+1] ;
list[n+1] = temp ;
}

/***Display result***/

if ( i > 0 )
{
printf("\n\nLIST OF ENTRIES : \n") ;

for ( m = 0 ; m < i ; m++ )
printf("%d\n", list[m]) ;
}

/***Free memory***/

for ( m = 0 ; m < i ; m++ )
free(list[m]) ;
}



I'm using djgpp on Windows :

I get in function main : line 25and 45 parsing argument 2 of strcmp
makes integer without a cast

line 55 assignement type from incompatible pointer type
line 56 error : incompatible type in assignement

Thanks,
Pascal
 
B

bartc

I'm learning and I entered twice the code below and it 's not working
with the same error messages.This code is a little above my
understanding of C however I'd like to understand the part that talks
about getting inputs into "unsized" char arrays of pointers.
{
printf("\nPerson %d (quit with \'0\'(zero) : ", i+1 ) ;

/* 1° the code first says \"0\" - i changed it to \'0\' - i'm not
sure */

The user will see "0" or '0'. To stop him actually typing the quotes, just
say 0 or 0 key.
gets(buffer) ;

Best to use fgets(), here, although probably nothing to do with your
problem; and fgets() puts 'n' at the end, so forget it for now.
if (strcmp(buffer, '0') ) /* same as above 1° */
} while ( i < 10 && strcmp(buffer, '0') ) ; /* same as 1° */

These strcmps are wrong. You're trying to compare against an empty string?
Then use "" not '0'. Against a string containing a single zero (ie. likely
ascii 48) character? Then use "0". And a result of 0 from strcmp means the
strings are equal.
if ( strcomp(list, list[n+1]) > 0 )

If this is meant to be strcmp then it should be ... strcmp. I haven't looked
at the rest of the code in detail.
 
M

Morris Keesan

#include <conio.h> /* getche */
I hope you realize that this is a non-standard header, which makes the
code totally non-portable.
Quoting Wikipedia: "conio.h is a header file used in old MS-DOS compilers
to create text user interfaces. It is not part of the C programming
language, the C standard library, ISO C nor is it required by POSIX."

int main(void)
{
char *list[10] ; /* 10 pointers array */
char *temp ; /* for sorting */

if (strcmp(buffer, '0') ) /* same as above 1° */ ....
} while ( i < 10 && strcmp(buffer, '0') ) ; /* same as 1° */ ....
I get in function main : line 25and 45 parsing argument 2 of strcmp
makes integer without a cast

Your code is poorly formatted, and without line numbers, but I'm guessing
that
the lines I've quoted are lines 25 and 45, and that you've typed in what
you
remember of the error message, instead of copying and pasting it, and that
the
error message really says "makes pointer from integer without a cast".
The second argument to strcmp should be a pointer. '0' is not a pointer;
it's
a character constant, which is a kind of integer. (Probably the number
48, which is
the ASCII value of the character '0'). If you're trying to test whether
buffer
contains a string consisting only of the character 0, then argument 2 to
strcmp
should be "0", not '0'.
line 55 assignement type from incompatible pointer type
line 56 error : incompatible type in assignement

Again, it would be good manners for you to identify the specific lines
involved,
rather than expecting people to count lines in an oddly-formatted (by the
time it
gets to Usenet) posting. But it looks like these are lines 55 and 56:
temp = list ;
list = list[n+1] ;

temp is a (char *).
list[n+1] is a (char *).
list is an array.

Neither of these two lines of code makes any sense.

In the first statement, on the right-hand side of the = operator,
the expression "list" is equivalent to "&list[0]",
i.e. the address of the first item in the array, i.e.
a pointer to a (char *), or a (char *).
You can't assign a (char **) to a (char **).
This is the "incompatible pointer type".

In the second statement, on the left-hand side of the assignment
operator, "list" does NOT get converted into the address of its
first element. "list", being an array, is not a variable which
can be assigned to.

I can't tell what you're actually trying to do here, but I'm not
trying very hard. What you need to do is go study some more
about pointers and arrays, and examine your code very carefully
and figure out what it is that you're trying to do with this
code. More comments would help, for a start.
 
D

Donkey Hottie

Morris Keesan said:
temp = list ;
list = list[n+1] ;

temp is a (char *).
list[n+1] is a (char *).
list is an array.

Neither of these two lines of code makes any sense.

In the first statement, on the right-hand side of the =
operator,
the expression "list" is equivalent to "&list[0]",
i.e. the address of the first item in the array, i.e.
a pointer to a (char *), or a (char *).
You can't assign a (char **) to a (char **).
This is the "incompatible pointer type".

In the second statement, on the left-hand side of the
assignment operator, "list" does NOT get converted into
the address of its
first element. "list", being an array, is not a variable
which
can be assigned to.

I can't tell what you're actually trying to do here, but
I'm not
trying very hard. What you need to do is go study some
more
about pointers and arrays, and examine your code very
carefully
and figure out what it is that you're trying to do with
this
code. More comments would help, for a start.

He's trying to sort the array with bubble sort algorithm.

if (strcmp(list, list[n+1]) > 0)
{
temp = list[n];
list[n] = list[n+1];
list[n+1] = temp;
}
 
B

bpascal123

I hope you realize that this is a non-standard header, which makes the  
code totally non-portable.
Quoting Wikipedia: "conio.h is a header file used in old MS-DOS compilers  
to create text user interfaces. It is not part of the C programming  
language, the C standard library, ISO C nor is it required by POSIX."


<<<<<<<<<<<<<<<<<<<<<

Hi Morris,

I realize conio has less meaning on today's systems and standards. As
a beginner, after 3-4 months (avg 5-10 hours a week) i have started
learning c, i tend to focus on making the code work first. As for this
code, credits should go to this book ; "Language C" MicroApplication
1996- G.Willms.

It's a pocket size book with a wide presentation of C. I find it
convenient because programms are well documented not line by line but
rather block by block. C libraries functions don't have a full
documentation so i need to do some research outside sometimes but
programs structures are well explained. Each book has its pros and
cons. If i get further with C, i hope i can get a "full desktop book"
with many references.

From now, as you're not the first personn to i'll pay attention and
i'll do what i can to rewrite stdio functions into current working
functions so it works on other systems such as Linux i also use side
by side with Microsoft Windows.

Thanks for making this relevant.
int main(void)
{
   char *list[10] ;                                /* 10 pointers array */
   char *temp ;                            /* for sorting */
           if (strcmp(buffer, '0') )                               /* same as above 1° */ ...
   } while ( i < 10     &&      strcmp(buffer, '0') ) ;  /* same as 1° */ ...
I get in function main : line 25and 45 parsing argument 2 of strcmp
makes integer without a cast

Your code is poorly formatted, and without line numbers, but I'm guessing  
that
the lines I've quoted are lines 25 and 45, and that you've typed in what  
you
remember of the error message, instead of copying and pasting it, and that  
the
error message really says "makes pointer from integer without a cast".
The second argument to strcmp should be a pointer.  '0' is not a pointer;  
it's
a character constant, which is a kind of integer.  (Probably the number  
48, which is
the ASCII value of the character '0').  If you're trying to test whether  
buffer
contains a string consisting only of the character 0, then argument 2 to  
strcmp
should be "0", not '0'.


line 55 assignement type from incompatible pointer type
line 56 error : incompatible type in assignement

Again, it would be good manners for you to identify the specific lines  
involved,
rather than expecting people to count lines in an oddly-formatted (by the  
time it
gets to Usenet) posting.  But it looks like these are lines 55 and 56:
                   temp = list ;
                   list = list[n+1] ;

temp is a (char *).
list[n+1] is a (char *).
list is an array.


==============================

I was hoping that if you'd paste this code in a text editor you would
get the same line numbering as i have (+/- 1 or 2)

line 25 if (strcmp(buffer, '0') )
line 45 } while ( i < 10 && strcmp(buffer, '0') ) ;

line 53 if ( strcmp(list, list[n+1]) > 0 )
line 55 temp = list ;
line 56 list = list[n+1] ;

==============================

Neither of these two lines of code makes any sense.

In the first statement, on the right-hand side of the = operator,
the expression "list" is equivalent to "&list[0]",
  i.e. the address of the first item in the array, i.e.
a pointer to a (char *), or a (char *).
You can't assign a (char **) to a (char **).
This is the "incompatible pointer type".

In the second statement, on the left-hand side of the assignment
operator, "list" does NOT get converted into the address of its
first element.  "list", being an array, is not a variable which
can be assigned to.

I can't tell what you're actually trying to do here, but I'm not
trying very hard.  What you need to do is go study some more
about pointers and arrays, and examine your code very carefully
and figure out what it is that you're trying to do with this
code.  More comments would help, for a start.

<<<<<<<<<<<<<<<<<<<<<

As I really want to understand this code and have it work, i will try
to post the comments of the author of the book as soon as i can.

Thx
Pascal
 
K

Keith Thompson

bartc said:
(e-mail address removed) wrote: [...]
gets(buffer) ;

Best to use fgets(), here, although probably nothing to do with your
problem; and fgets() puts 'n' at the end, so forget it for now.

You mean '\n' (i.e., a new-line character).

And it's never too soon to learn to avoid gets().
 
B

bpascal123

Hi,

Under Linux, I made this minor changes. I'd still get message errors
such as "...assignment incompatible...type" but i think now the code
can now apply to linux as well as windows.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

line 4 (starting from #include <stdio.h>) : deleted stdio.h ;

line 17 (next to line 4) : fgets(buffer, 128, stdin) ;

line 26 (next to line 17) : added while ( getchar() != '\n' ) ; to get
rid of buffer entry(ies) like '\n' getch() would avoid ;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I haven't yet taken in consideration posts from this discussion about
changing some parts of the author's code.

I don't want to spend too much time as a consider this quite above my
current level (for instance, it's first time i deal with malloc...).
However, I hope to make this code work with your help.

One question : under gcc, can i get more meaningfull error message?
What would be the command ? :
gcc parlst3L.c -o -w -pedantic parlst3L

Gcc return "parlst3L : No such file or directory

Thanks
Pascal
 
B

bartc

Keith Thompson said:
bartc said:
(e-mail address removed) wrote: [...]
gets(buffer) ;

Best to use fgets(), here, although probably nothing to do with your
problem; and fgets() puts 'n' at the end, so forget it for now.

You mean '\n' (i.e., a new-line character).

And it's never too soon to learn to avoid gets().

Getting rid of that pesky '\n' is more trouble that you might think,
especially when you don't want extra-long input lines generating unexpected
multiple inputs. I tried this:

#include <stdio.h>

/* ngets(): Safer form of gets():
Takes buffer size parameter (or is it argument?:)
Any trailing '\n' removed
Extra characters on the line ignored
Usage: ngets(buffer,n);
*/

char* ngets(char* dest,int n){
char *p;
char buffer[100];

fgets(dest,n,stdin);

/* Remove any trailing newline char */
p=dest;
while (*p) {
if (*p=='\n') {
*p=0;
return dest;
}
++p;
}

/* No newline so skip any superflous input on this line */
while(1) {
fgets(buffer,sizeof buffer,stdin);
p=buffer;
while (*p)
if (*p++ =='\n') return dest;
}
return dest;
}
 
B

Ben Bacarisse

Under Linux, I made this minor changes. I'd still get message errors
such as "...assignment incompatible...type" but i think now the code
can now apply to linux as well as windows.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

line 4 (starting from #include <stdio.h>) : deleted stdio.h ;

line 17 (next to line 4) : fgets(buffer, 128, stdin) ;

line 26 (next to line 17) : added while ( getchar() != '\n' ) ; to get
rid of buffer entry(ies) like '\n' getch() would avoid ;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This makes it hard to comment on the code.
I haven't yet taken in consideration posts from this discussion about
changing some parts of the author's code.

I don't want to spend too much time as a consider this quite above my
current level (for instance, it's first time i deal with malloc...).
However, I hope to make this code work with your help.

You need to turn up warnings and run the result only when you either
get no messages at all or when you understand that the message is
genuinely simply some advice.
One question : under gcc, can i get more meaningfull error message?
What would be the command ? :
Gcc return "parlst3L : No such file or directory

(you meant to write: 'gcc parlst3L.c -o parlst3L -w -pedantic' -- the
output file name goes after the -o)

I'd use:

gcc -std=c89 -pedantic -Wall -Wextra

There are a bunch of other helpful warnings you can turn on. I almost
always use:

-Wstrict-prototypes -Wbad-function-cast -Wcast-qual -Wshadow -Wundef
-Wconversion -Wwrite-strings

as well. (This last one makes gcc non-conforming is very subtle cases
but it useful enough that I don't care.)

You still have a number of errors as you say. '0' is a char not a
string so you need "0" is strcmp calls. You have several places where
you write 'line' but 'line[x]' is needed. I can't correct them
without looking in detail because I don't know what the index should
be but since this is from some source or other, presumably it is just
a coping mistake that you can correct simply enough.

It is a minor point, but using odd layout discourages experienced
people from reading the code. It just looks too messy. At least,
that is my first reaction to it. You can be a clever maverick in your
algorithms, but you should be conforming sheep in your layout.
 
B

Ben Bacarisse

Richard Heathfield said:
Here's an input subsystem based on fgets, that truncates input at a
given limit (discarding the rest of the line) and drops the
newline:

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

int str_terminate_at(char *s, int c)

I prefer not to perpetuate the "int for char" problem upwards when
there is no value in allowing non-character arguments (EOF being the
only reasonable example). I'd make c a char (or an unsigned char) and
put the cast in the strchr call once and for all. Very much a matter
of taste, but the failure to cast is so common that defending against
it is probably worth while.
{
char *t = strchr(s, c);
if(t != NULL)
{
*t = '\0';
}
return t != NULL;
}

int f_discard_token(FILE *f, int token_ends)

Here there is value in having an int since f_discard_token(stdin, EOF)
makes perfect sense.
{
int ch;
while((ch = getc(f)) != EOF && ch != token_ends)
{
continue;
}
return ch == token_ends;

Because of this possibility, I'd write:

return !ferror() && ch == token_ends;

so that a return of 1 from a call such as the example above truly
indicates successfully discarding to end-of-file.
}

char *aggressive_fgets(char *s, size_t len, FILE *f)
{
char *result = fgets(s, len, f);

For maximum portability, it might be better to make len an int. If
not it should probably be tested so as to avoid the implementation
defined consequences of the conversion.
 
B

bpascal123

Hi,

I think this code below is working both on linux and windows. A very
few minor changes were needed. Published in 1996 doesn't make this
code so "out of range".


/* Manage 10 strings in an array of pointeurs */

#include <stdio.h> /* printf, gets */
#include <string.h> /* strcmp, strcpy, strlen */
#include <stdlib.h> /* malloc, free, exit */

int main(void)
{
char *list[10] ;
char *temp ;
char buffer[128] ;
int i = 0 ;
int m, n, rep ;

printf("\n\nINITIALISATION OF A LIST\n") ;
printf("\nMaximum of 10 entries in this format :\n") ;
printf("Last name, first name (country)\n") ;

do
{
printf("\nEntry %d : ", i+1 ) ;
fgets(buffer, 128, stdin) ;

if (strcmp(buffer, "0"))
{
if ((list = (char *) malloc(strlen(buffer) + 1)) == NULL )
{
printf("\nOut of memory.\n") ;
if ( i > 0 )
{
while ( getchar() != '\n') ;
printf("\nDisplay current listing ? (o/n)") ;

if ( rep == 'o' )
break ; /* does break quit the if from if (strcmp(buffer,
"0")) ??? */
}
exit(1) ;
}
strcpy(list, buffer) ;
i++ ;
}
} while ( i < 10 && strcmp(buffer, "0") ) ;


for ( m = i - 1 ; m > 0 ; m-- )

for ( n = 0 ; n < m ; n++ )
if ( strcmp(list[n], list[n+1]) > 0 ) /* The author wrote list
instead of list[n], could it had been : strcmp( *list, *(list+1) ) ???
*/
{
temp = list[n] ;
list[n] = list[n+1] ;
list[n+1] = temp ;
}

if ( i > 0 )
{
printf("\nENTRY LISTING : \n") ;
for ( m = 0 ; m < i ; m++ )
printf("%s\n", list[m] ) ;
}

for ( m = 0 ; m < i ; m++ )
free(list[m]) ;
}

Recopied from this book : PC Poche Langage C from G.Willms published
by Micro Application...hope there won't be copyright big issues...
 
B

bpascal123

I understand bringing code from a book to the internet could be
sensitive even in the process of learning. I'll try to work on blocks
of code now when i'm not the originator.
 
B

bpascal123

You need to turn up warnings and run the result only when you either
get no messages at all or when you understand that the message is
genuinely simply some advice.


(you meant to write: 'gcc parlst3L.c -o parlst3L -w -pedantic' -- the
output file name goes after the -o)

I'd use:

 gcc -std=c89 -pedantic -Wall -Wextra

There are a bunch of other helpful warnings you can turn on.  I almost
always use:

 -Wstrict-prototypes -Wbad-function-cast -Wcast-qual -Wshadow -Wundef
 -Wconversion -Wwrite-strings

as well.  (This last one makes gcc non-conforming is very subtle cases
but it useful enough that I don't care.)

<<<< Thanks
It is a minor point, but using odd layout discourages experienced
people from reading the code.  It just looks too messy.  At least,
that is my first reaction to it.  You can be a clever maverick in your
algorithms, but you should be conforming sheep in your layout.

<<<< OOps, Read it after my last posting
 
B

Ben Bacarisse

Richard Heathfield said:
Ben Bacarisse said:


Er, kindasorta, yes. Anyway, I always use int for Booleans.

I meant that int is clearly a good choice for this second parameter
since it makes sense to permit passing EOF to this function. I don't
see the connection with Booleans.

<snip>
 
A

Anand Hariharan

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

int str_terminate_at(char *s, int c)
{
(...)
<snip>

IANAL, but does not the standard reserve functions with names starting
with 'str'?

- Anand
 
M

Morris Keesan

I realize conio has less meaning on today's systems and standards.

It had "less meaning" on any system and standard, unless one's goal
was to write code which could only ever run on Microsoft operating
systems.

I was hoping that if you'd paste this code in a text editor you would
get the same line numbering as i have (+/- 1 or 2)

It's asking a lot, to expect people to paste your code into a text editor
to help you solve your problems. And (+/- 1 or 2) lines of code is
almost as good as not giving line numbers at all.
 
B

Ben Pfaff

Anand Hariharan said:
IANAL, but does not the standard reserve functions with names starting
with 'str'?

Only when str is followed by a lowercase letter:

7.26.11 String handling <string.h>

1 Function names that begin with str, mem, or wcs and a lowercase
letter may be added to the declarations in the <string.h>
header.
 
A

Anand Hariharan

Only when str is followed by a lowercase letter:

     7.26.11 String handling <string.h>

1    Function names that begin with str, mem, or wcs and a lowercase
     letter may be added to the declarations in the <string.h>
     header.


Ben -

Thank you for the standard quote and taking the time to clarify.

sincerely,
- Anand
 
B

bpascal123

It's asking a lot, to expect people to paste your code into a text editor
to help you solve your problems.  And (+/- 1 or 2) lines of code is
almost as good as not giving line numbers at all.

As a early learner, i can't imagine someone being able to read code
displayed in some text/input box and get right to a message
error...Maybe i'll get to that level, for now i am investing quite
some time on it but C is quite tremendous to learn and i sometimes
feel desesperate of spending hours on "basic stuffs"...

Thanks
 
B

bpascal123

Hi there,

It could be another topic but this a very brief question. When running
these lines below i get these message errors on Windows gcc :

For ( i = 0 ; i != isspace(T1d) ; i++ )
cnt1++ ;

For ( i = cnt1 ; i != (isspace(T1d)) ; i++ )
cnt2++ ;

For ( i = cnt2 ; i != (isspace(T1d)) ; i++ )
cnt3++ ;

In function 'main':
error: expected ')' before ';' token
error: expected ';' before 'cnt1'
error: expected ')' before ';' token
error: expected ';' before 'cnt2'
error: expected ')' before ';' token
error: expected ';' before 'cnt3'

I don't understand. Does this have to do with syntax ?

Thanks,
Pascal
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top