Thread: Would like some help

  1. #1
    Registered User
    Join Date
    Aug 2019
    Posts
    138

    Would like some help

    Code:
    int main()
    {
        // some code
        
        char select[] = makeSelection(); // invalid initializer
        puts(select);
    
        // some code
        return 0;    
    }
    
    const char * makeSelection() // don't understand the const * char
    {        
        //some code
        gets(choice);
        return choice;
    }
    Re the two queries above. I would be grateful for some help / explanation. Thank you.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,728
    In C, you need to declare the prototype of the function (or define it altogether) before you use it. The prototype is just the function without the body, like this:
    Code:
    // Do this before main
    const char * makeSelection();
    A "char*" is a pointer to "char". A "const char*" is a pointer to "const char".

    I'd like to mention a couple of things you didn't ask about

    1) All functions that take no parameters should be declared/defined using "(void)", like this:
    Code:
    const char* makeSelection(void);
    because, in C in particular, an empty parameter list doesn't mean it takes no arguments. Strange, I know, but so it is.

    2) Do not use "gets()". Why gets() is bad / Buffer Overflows - Cprogramming.com
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Aug 2019
    Posts
    138
    Quote Originally Posted by GReaper View Post
    In C, you need to declare the prototype of the function (or define it altogether) before you use it. The prototype is just the function without the body, like this:
    Code:
    // Do this before main
    const char * makeSelection();
    A "char*" is a pointer to "char". A "const char*" is a pointer to "const char".

    I'd like to mention a couple of things you didn't ask about

    1) All functions that take no parameters should be declared/defined using "(void)", like this:
    Code:
    const char* makeSelection(void);
    because, in C in particular, an empty parameter list doesn't mean it takes no arguments. Strange, I know, but so it is.

    2) Do not use "gets()". Why gets() is bad / Buffer Overflows - Cprogramming.com
    --------------------------------------------------------------------------
    I did declare the function. Have now added "void" though.
    I am still getting the same errors.

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    501
    Quote Originally Posted by zach View Post
    --------------------------------------------------------------------------
    I did declare the function. Have now added "void" though.
    I am still getting the same errors.
    You didn't declare the prototype! @GReaper was clear in his first line:
    Quote Originally Posted by GReaper
    In C, you need to declare the prototype of the function (or define it altogether) before you use it
    The words "prototype" and "before" are big hints!

    You will get the same errors because your code is wrong: Assigning a pointer to an incomplete array is wrong and fail to declare a variable (choice)...

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,437
    And remember that you can't return a pointer to a variable that is local to some function. How is "choice" defined, it's not a "const" since you're trying to get a value from the user so I question your return type as well.

    It would be helpful if you posted a small complete program that illustrates the problem, instead of just a couple of meaningless snippets.

  6. #6
    Registered User
    Join Date
    Aug 2019
    Posts
    138
    Quote Originally Posted by jimblumberg View Post
    And remember that you can't return a pointer to a variable that is local to some function. How is "choice" defined, it's not a "const" since you're trying to get a value from the user so I question your return type as well.

    It would be helpful if you posted a small complete program that illustrates the problem, instead of just a couple of meaningless snippets.
    ---------------------------------------------
    This is the code (write() is defined in prelims.h)

    Code:
    #include "prelims.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include<conio.h>
    
    struct about
    {
        char name[35];
        char actionCode[2];
    };
    
    int dataEntry();
    const char * makeSelection(void);
    char choice[5];    
    
    int main()
    {
        prelims();
    
        char select[] = makeSelection(); // error line
        write(0,0,select);
        dataEntry();    
        
    
        return 0;    
    }
    
    int dataEntry()
    {
        struct about data;
        gotoxy(0,0);
        printf("Concerns    : ");
        gets(data.name);
        char *p;
        if ( (p=strchr(data.name,'\n')) != NULL ) *p = '\0';
        printf("Action Code : ");
        gets(data.actionCode);
        if ( (p=strchr(data.actionCode,'\n')) != NULL ) *p = '\0';
        FILE *fptr;
        fptr=fopen("K:\\descrip", "a+");    
        fwrite(&data, sizeof(struct about), 1, fptr);
        fclose(fptr);    
        return 0;
    }
    
    const char * makeSelection() // read this how to do it but dont understand why
    {        
        gotoxy(0,25);
        char line [173];
        puts(memset(line,196,172));
        write(5,27,"What would you like to do?");
        write(5,28,"Enter a description = 1 ");
        gets(choice);
        return choice;
    }

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    4,437
    ---------------------------------------------
    This is the code (write() is defined in prelims.h)
    So, why didn't you post that code as well? You do know that you should not have executable code inside a header file, correct?

    Why are you still using gets()? That dangerous function can never be used safely and has actually been removed from the language with the current standard.

    Why are your functions still defined with no parameters? Why is choice a global variable? Why not just pass that variable to the function, along with it's size:

    Code:
    void makeSelection(char *choice, size_t length);
    So many other problems, fix the above issues then we can address the rest.

  8. #8
    Registered User
    Join Date
    Aug 2019
    Posts
    138
    The why's are because I started to look at C a short while ago, so there is little I know. I worked through a tutorial and took notes. Tutorials don't cover the stuff I was up against in the code referred to. No, I don't know about executable code not belonging inside a header. Why do I still have gets()? Because I first wanted to address the errors the compiler is reporting before polishing up the code.

    I'd please like to ask for an explanation of size_t length.

  9. #9
    Registered User
    Join Date
    Aug 2019
    Posts
    138
    Jim Bluberg asked to see the prelims.h code. Here it is:

    Code:
    #ifndef temp
    #define temp
        extern void prelims(void);
        extern void gotoxy(short x, short y); 
        extern void write (short a, short b, char words[]);
    #endif
    #include<windows.h>
    #include<conio.h>
    #include<stdio.h>
    
    void prelims(void)
    {
        HANDLE handle;
        handle = GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleTextAttribute(handle,14);
        CONSOLE_SCREEN_BUFFER_INFO info;GetConsoleScreenBufferInfo(handle, &info);
        COORD new_size = 
         {
            info.srWindow.Right - info.srWindow.Left + 1,
            info.srWindow.Bottom - info.srWindow.Top + 1
         };
        SetConsoleScreenBufferSize(handle, new_size);
        HWND wh = GetConsoleWindow();
        MoveWindow(wh, 0, 0, 1280, 670,TRUE);
    }
    
    extern void gotoxy(short x, short y) 
        {
            COORD pos = {x, y};
            SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
        }
    
    extern void write (short a, short b, char words[])
        {
            gotoxy(a,b);
            puts(words);
        }

  10. #10
    Registered User
    Join Date
    May 2010
    Posts
    4,437
    Okay so everything other than the first 4 or 5 lines should be in another c source file, not inside that header (from the #ifndef till the #endif stay in the header).

    I'd please like to ask for an explanation of size_t length.
    What do you need to know? Did you try to use your favourite search engine to look up "size_t", if that's what you don't understand?

    Why do I still have gets()? Because I first wanted to address the errors the compiler is reporting before polishing up the code.
    In this case that is a really poor reason. The gets() function is a big part of your problems and should be fixed now.

    The errors are probably being caused because you are trying to "initialize" an array of char with a pointer being returned from the function, you can't do that.

    Stop using the global variables and learn to properly pass values back and forth to your functions as required.

  11. #11
    Registered User
    Join Date
    May 2010
    Posts
    4,437
    By the way if you were using a modern C compiler compiling to the current C standard you would be getting many more errors than the few you seem to be worrying about. If your going to try to learn C you should be learning modern C (C99 or preferably C11) not the outdated C90 that you appear to be using with your outdated compiler (Visual C doesn't fully support anything other than C90).

  12. #12
    Registered User
    Join Date
    Aug 2019
    Posts
    138
    Quote Originally Posted by jimblumberg View Post
    By the way if you were using a modern C compiler compiling to the current C standard you would be getting many more errors than the few you seem to be worrying about. If your going to try to learn C you should be learning modern C (C99 or preferably C11) not the outdated C90 that you appear to be using with your outdated compiler (Visual C doesn't fully support anything other than C90).
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    I am using DEV-C (I also tried Pelle C but the libraries were limited)
    I will polish up prelims as you say
    I removed gets() from the code and am back in the situation where I input data. name and the code flips on without allowing for the next entry.
    I was trying scanf() instead of gets() because the suggested alternative for gets() freaked.

  13. #13
    Registered User
    Join Date
    May 2010
    Posts
    4,437
    Show what you tried? The fgets() function should be the "replacement". However you need to insure that you array is big enough to hold both the end of string character and the end of line character that fgets() adds to the string.

    I removed gets() from the code and am back in the situation where I input data. name and the code flips on without allowing for the next entry.
    I would be willing to bet that you're overflowing your arrays with your input. Did you limit the number of characters scanf() will try to retrieve into your string, if not then you're no better off than using gets(). You need to use a function that limits the number of characters it will try to retrieve to "eliminate" buffer overflow problems.

  14. #14
    Registered User
    Join Date
    Aug 2019
    Posts
    138
    Jim, I scrapped part of my code and started again, applying your advice. After a good bit of tail biting I think I am finally making progress. I'd like to thank you. Zach.

  15. #15
    Registered User
    Join Date
    May 2010
    Posts
    4,437
    By the way I would recommend Pelles C over DEV-C as it is probably more up to date with the current standards.

    Also if the libraries you're talking about are things like conio, then you would probably be better off without it in the first place.

Popular pages Recent additions subscribe to a feed

Tags for this Thread