When trying to compile a C program including the code below, I keep getting this error and I don't know what to do to fix it. Please explain if you can!

Complete code may be downloaded from my website at www.atrixnet.com/cquestion.zip (It's only 2 Kb)

I suppose I'll attach it to this post too, since that appears to be an available feature on this board :)

COMPILATION ATTEMPT:
tommy@city-it ~/cdevel
$ gcc -Wall -ansi -pedantic -mno-cygwin -I . -o myfirstlib myfirstlib.c

ERROR:
myfirstlib.c: In function `main':
myfirstlib.c:14: warning: passing arg 2 of `strcpy' makes pointer from integer without a cast
myfirstlib.c:20: warning: passing arg 2 of `strcpy' makes pointer from integer without a cast

CODE SUMMARY (main program):

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

int anumber;
char astring[255];

int
main ()
{
  printf ("This is the first time I've tried to '#include' my library!\n\n");

  anumber = getnum("Enter some kind of integer: ");
  strcpy(astring, getstring("Enter your name: "));

  printf("\nThank you, %s.  You entered %d\n", astring, anumber);

  while (getyn("\nDo you want to go again? [Y/n]")) {
     anumber = getnum("Enter some kind of integer: ");
     strcpy(astring, getstring("Enter your name: "));

     printf("\nThank you, %s.  You entered %d\n", astring, anumber);
   }

   printf("\nBye.\n");

  return (0);
}

CODE SUMMARY (from myfuncs.h):

/* will act as the buffer into which user's response will be stored */
char lineofinput[255];

/* grabs a string from the command prompt */
char
getstring (char strquestion[255])
{
  /* reset */
  char lineofinput[255];

  if (strlen (strquestion))
    printf ("%s", strquestion);

  fgets (lineofinput, sizeof (lineofinput), stdin);

  /* while we get an empty response */
  while (strlen (lineofinput) == 1)
    {
      if (strlen (strquestion) == 1)
         printf ("Empty answers not permitted.  Please try again: ");

      return (getstring (lineofinput));
    }

  return (sprintf("%s", lineofinput));
}

MY COMPILER:
tommy@city-it ~/cdevel
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.3.3/specs
Configured with: /gcc/gcc-3.3.3-3/configure --verbose --prefix=/usr --exec-prefi
x=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,java,objc,
pascal --enable-nls --without-included-gettext --enable-libgcj --with-system-zlib --enable-interpreter --enable-threads=posix --enable-java-gc=boehm --enable-sjlj-exceptions --disable-version-specific-runtime-libs --disable-win32-registry
Thread model: posix
gcc version 3.3.3 (cygwin special)

Well, your getstring returns a single char and not a char*.

/* grabs a string from the command prompt */
char
getstring (char strquestion[255])
{
  /* reset */
  char lineofinput[255];

  if (strlen (strquestion))
    printf ("%s", strquestion);

  fgets (lineofinput, sizeof (lineofinput), stdin);

  /* while we get an empty response */
  while (strlen (lineofinput) == 1)
    {
      if (strlen (strquestion) == 1)
         printf ("Empty answers not permitted.  Please try again: ");

      return (getstring (lineofinput));
    }

  return (sprintf("%s", lineofinput));
}

But what you attempt to return is more worrisome.

You may want to take a peek at this.

Well, your getstring returns a single char and not a char*.

Yes but how do I change that?

But what you attempt to return is more worrisome.

I'm sorry? What do you mean?

You may want to take a peek at this.

Unfortunately that isn't providing me with any answers to the question I've asked. Remember I'm a total newbie? Please help me out here by guiding me with a little easier terms to understand.

Thanks for responding to me!

>Yes but how do I change that?
I would think it would be obvious:

char *
getstring (char strquestion[255])

>I'm sorry? What do you mean?
sprintf returns the number of characters printed, not a string of any sort, which is what your use of getstring suggests. You could return lineofinput, and that would satisfy the type system, but then you would have problems because lineofinput is a local variable and is destroyed when the function returns. A much better solution would be to pass a pointer to the buffer to getstring. Then you can return a pointer to the buffer with no problem:

#include <stdio.h>

char *getstring ( char buffer[], int size )
{
  if ( fgets ( buffer, size, stdin ) == NULL )
    return NULL;

  return buffer;
}

int main ( void )
{
  char buffer[BUFSIZ];

  if ( getstring ( buffer, sizeof buffer ) != NULL )
    printf ( "%s\n", buffer );

  return 0;
}

>Unfortunately that isn't providing me with any answers to the question I've asked.
Perhaps not the question you asked now. If we give you a link (Dave or I in particular), we think you need the information whether you asked for it or not.

>Please help me out here by guiding me with a little easier terms to understand.
You read book. Use reference. It help make code good.

>>Yes but how do I change that?
>I would think it would be obvious:

Seriously? I just started messing with C a few days ago. I've only ever programmed in Perl and Python. The example you provided works but I still have no idea why... I'll continue to research it, but I thought the point of this board was to get help with things, not get cryptic responses that provide more questions than I started with.

So far I'm very disappointed with the quality of help I've received. It's showing me how weak the community is around C and C++ whereas the community around python and perl leaves you guys looking like... well... words that shouldn't be uttered in public foura.

And please don't tell me, "well if you love perl so much why don't you just go away"... That is so below what I hoped you'd prove to be -helpful, friendy.

char *
getstring (char strquestion[255])

Like I said -works great but means nothing to me.

>sprintf returns the number of characters printed, not a string of any sort, which is what your use of getstring suggests. You could return lineofinput, and that would satisfy the type system, but then you would have problems because lineofinput is a local variable and is destroyed when the function returns. A much better solution would be to pass a pointer to the buffer to getstring. Then you can return a pointer to the buffer with no problem:

#include <stdio.h>

char *getstring ( char buffer[], int size )
{
  if ( fgets ( buffer, size, stdin ) == NULL )
    return NULL;

  return buffer;
}

int main ( void )
{
  char buffer[BUFSIZ];

  if ( getstring ( buffer, sizeof buffer ) != NULL )
    printf ( "%s\n", buffer );

  return 0;
}

Thanks this is good information, but still doesn't /explain/ anything, like what the "*" does and where you get "BUFSIZ". :(

>>Unfortunately that isn't providing me with any answers to the question I've asked.
>Perhaps not the question you asked now. If we give you a link (Dave or I in particular), we think you need the information whether you asked for it or not.

OK.

>>Please help me out here by guiding me with a little easier terms to understand.
>You read book. Use reference. It help make code good.

I really can't believe you just said that. I'm already working out of a book. Dare I ask if you know of any other places I could receive better help with C than this?

where you get "BUFSIZ"

Wait, sorry I forgot BUFSIZ is in the faq you showed me, but not "*".

"*" are pointers they point to a memory address.
Dave and Narue are not trying to be mean and cryptic. They are just trying to get you to work things out on your own. Most of us fell that it is a disservice to tell you everything and you not find it out on your own.

Am I to understand then that there's no way for a function to return a true string in C :?:

aka - return("Hello, my name is Simon");

Of course there is. Like dave and prelude saud you have to use the char* type.
e.g

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

char *getSomeString(void);

int main(void)
{
    char mainString[strlen(getSomeString()) + 1];
    strcpy(mainString,getSomeString());
    printf("%s",mainString);
    getchar();
}

char *getSomeString(void)
{
    return "Some String";
}

Now I think I did the printf right I am a C++ man ;)

Of course there is. Like dave and prelude saud you have to use the char* type.
e.g

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

char *getSomeString(void);

int main(void)
{
    char mainString[strlen(getSomeString()) + 1];
    strcpy(mainString,getSomeString());
    printf("%s",mainString);
    getchar();
}

char *getSomeString(void)
{
    return "Some String";
}

Now I think I did the printf right I am a C++ man ;)

Ok but i'm still in the dark, I'm sorry. If you say char *getSomeString... you aren't really returning a string, you're returning a pointer right? DOH!

And is it bad to say...

char mainString[] = getSomeString();

My Oreilly book says...

C has a special shorthand for initializing strings: Surround the string with double quotes to simplify initialization...

char name[] = "Sam";

The dimension of name is 4 because C allocates a place for the '\0' character that ends the string.

Am I to understand then that there's no way for a function to return a true string in C :?:

aka - return("Hello, my name is Simon");

No, you cannot.

No, you cannot.

So only pointers then...?

I guess will start researching pointers now. My knowledge of those is pretty dern limited so far. In the examples I've seen in everyone's code, it confuses me that there seems to be no manual dereferencing of pointers, just declarations of them and then usage of them as if they were regular vars. In Perl you have to manually dereference pointers, but here it seems as though the compiler does this for you. Very strange. Very error prone too.

Lots of new posts...

>Seriously? I just started messing with C a few days ago. I've only ever programmed in Perl and Python.
Yes, seriously. Not because I think you should be some sort of programming genius, but because Dave told you. Allow me to quote: "Well, your getstring returns a single char and not a char*." To me, the next logical step is to change char to char * and see what happens.

>The example you provided works but I still have no idea why...
With only a few days of C experience, do you really expect to understand the deep secrets of the language? I've been working with C for nearly a decade and I still haven't done that. When first starting out, there are just some things you need to take on faith and realize that things will become clear later.

>I thought the point of this board was to get help with things, not get cryptic responses
I'm sorry, but I just can't dumb down C to the point where a person with "a few days" of experience would get it all. It's just not possible unless you have experience with a lower level language. If you think I'm being cryptic, just go anywhere else and ask your question.

>So far I'm very disappointed with the quality of help I've received. It's
>showing me how weak the community is around C and C++ whereas the
>community around python and perl leaves you guys looking like... well...
>words that shouldn't be uttered in public foura.
It's obvious that you were biased against us to begin with. What you call "weak" is merely different, and your reaction isn't likely to encourage us to make your stay here more pleasant.

>And please don't tell me, "well if you love perl so much why don't you just go away"...
Yet more proof that you were maintaining an unreasonable bias. What reason would we have to tell you to go away? Aside from your being an ass about some imagined insult. :rolleyes:

>Like I said -works great but means nothing to me.
Tough. If I explained pointers to you then you would only say I was being "cryptic". In all honesty, everyone who's new to C has trouble with pointers for a very long time. An explanation wouldn't help much, so I didn't provide one.

>but still doesn't /explain/ anything, like what the "*" does and where you get "BUFSIZ".
The second part is actually a good question. The answer to the first is that it designates a pointer, and that you would only be more of an ass to me if I gave you an accurate description of what a pointer is. The answer to the second is that BUFSIZ is a macro defined in stdio.h. It's a good size for a buffer, so you may see it used often for lines read from input streams.

Macros are a way to textually substitute something meaningful, like BUFSIZ, with a literal value, like 1024. After preprocessing, my program would look something like this:

/* A lot of stuff */

char *getstring ( char buffer[], int size )
{
  if ( fgets ( buffer, size, stdin ) == (void*)0 )
    return (void*)0;

  return buffer;
}

int main ( void )
{
  char buffer[1024];

  if ( getstring ( buffer, sizeof buffer ) != (void*)0 )
    printf ( "%s\n", buffer );

  return 0;
}

BUFSIZ would look something like this if you opened stdio.h and took a peek:

#define BUFSIZ 1024

>I really can't believe you just said that.
What do you want me to say? Programming is hard. C is exceptionally hard. As I said, I can't dumb down the language to suit your inexperience.

>Am I to understand then that there's no way for a function to return a true string in C
There's no such thing as a true string in C. A string is an array of characters terminated by a null character ('\0'). However, because there is an interesting relationship between arrays and pointers, you can return a pointer to char and that gives you a similar effect as returning a pointer:

char *f ( void )
{
  return "This is a string";
}

However, the rules are convoluted and not entirely easy to understand, which is why I didn't explain it to begin with and why I'll stop there. I don't want to run you off by making you think that C is too obscure to learn.

>And is it bad to say...
Actually, it's illegal. What you're trying to do is initialize an array of char, but that can only be done with an initialization list:

char a[] = {'o', 'n', 'e', '\0'}; /* Initialize to "one" */

Or a string literal:

char a[] = "one";

The former requires that you add the null character yourself, but the latter will add it automatically. Since your code is neither of these, it's illegal. However, it would be legal if you declared the variable as a pointer rather than an array:

char *mainString = getSomeString();

>that there seems to be no manual dereferencing of pointers
You can dereference pointers manually, but if you're only working with strings, it may not seem that way:

#include <stdio.h>

int main ( void )
{
  int i = 10;
  int *p = &i;

  printf ( "%d\n", *p ); /* Dereference. Prints 10 */

  return 0;
}

>In Perl you have to
You would really be better off not comparing Perl to C when working with new concepts. For example, Perl references and C pointers are sufficiently different enough to cause you fits.

As a parting thought, I really do care whether you succeed or fail with C. I just don't have a lot of time to give you detailed explanations that would likely do no good for some time to come. The Perl and Python communities are really buddy-buddy. It's like a programming orgy. The C community is no less friendly, but we cut through the crap and say it like it is. That can often be misinterpreted as being mean. So try to put any bias and initial problems behind you and you can learn a lot here. To be perfectly honest, I don't care about making friends, so I'm even less friendly than others. I just want to pass on my knowledge and help others as much as possible.

If that's not something you can handle, try www.cpp-home.com. They're generally a little less intense, but they work mostly with C++ and you're more likely to get several bad answers than one really fantastic answer to any of your questions.

This article has been dead for over six months. Start a new discussion instead.