Thread: Pointer with strcat() and assignment

  1. #1
    Registered User
    Join Date
    Dec 2014
    Posts
    10

    Exclamation Pointer with strcat() and assignment

    Hello guys. I am stuck help me out.
    I am trying to write a code that simply adds "s" in the end of name. In other words; Singular to plural (no ies es rule; just "s" in the end)
    Code is here:

    Code:
    #include<stdio.h>
    #include<conio.h>
    #include<string.h>
    main()
    {
         char *ptrname[35];
         ptrname[0]="Cow";
         ptrname[1]="Parrot";
         for(int i=0;i<2;i++)
         {
         strcat(ptrname[i],"s");
         printf("%s\n",ptrname[i]);
         }
        
         getch();
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,784
    Use a 2D array instead, making sure that there's enough space in each inner array to hold both the 's' to be added and the null character. You will also need to initialise this 2D array instead of using assignment, or use strcpy.

    At the moment, your pointers point to the first character of string literals, so you end up trying to modify string literals, resulting in undefined behaviour.

  3. #3
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    729
    Quote Originally Posted by waqaradil89 View Post
    Hello guys. I am stuck help me out.
    I am trying to write a code that simply adds "s" in the end of name. In other words; Singular to plural (no ies es rule; just "s" in the end)
    Code is here:

    Code:
    #include<stdio.h>
    #include<conio.h>
    #include<string.h>
    main()
    {
         char *ptrname[35];
         ptrname[0]="Cow";
         ptrname[1]="Parrot";
         for(int i=0;i<2;i++)
         {
         strcat(ptrname[i],"s");
         printf("%s\n",ptrname[i]);
         }
        
         getch();
    }
    ptrname[i] contains a pointer to a Constant String. You cannot strcat() a string onto a string constant.
    main() should be int main(void), and you should return 0; at the end of your main function to indicate to the O/S that the app executed correctly, or a non-zero value if the app failed.
    Please don't use conio, and it is non-standard.
    I also recommend defining "int i" at the start of the main() function, not in the for() loop. Not allowed in all versions of the C standard.

  4. #4
    Registered User
    Join Date
    Dec 2014
    Posts
    10
    Quote Originally Posted by rstanley View Post
    ptrname[i] contains a pointer to a Constant String. You cannot strcat() a string onto a string constant.
    What is the solution ?


    Quote Originally Posted by rstanley View Post
    main() should be int main(void), and you should return 0; at the end of your main function to indicate to the O/S that the app executed correctly, or a non-zero value if the app failed.
    Please don't use conio, and it is non-standard.
    I also recommend defining "int i" at the start of the main() function, not in the for() loop. Not allowed in all versions of the C standard.
    Thanks for the suggestion.

  5. #5
    Registered User
    Join Date
    Dec 2014
    Posts
    10
    You will also need to initialise this 2D array instead of using assignment, or use strcpy.
    What does it mean? Is there any other way of initialisation?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,784
    Quote Originally Posted by waqaradil89
    What does it mean? Is there any other way of initialisation?
    In other words, if you write:
    Code:
    char ptrname[35][20];
    then you cannot continue to write:
    Code:
    ptrname[0] = "Cow";
    ptrname[1] = "Parrot";
    Rather, you either have to use initialisation:
    Code:
    char ptrname[35][20] = {"Cow", "Parrot"};
    or use strcpy or some other suitable function:
    Code:
    strcpy(ptrname[0], "Cow");
    strcpy(ptrname[1], "Parrot");
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Dec 2014
    Posts
    10
    Quote Originally Posted by laserlight View Post
    In other words, if you write:
    Code:
    char ptrname[35][20];
    then you cannot continue to write:
    Code:
    ptrname[0] = "Cow";
    ptrname[1] = "Parrot";
    Rather, you either have to use initialisation:
    Code:
    char ptrname[35][20] = {"Cow", "Parrot"};
    or use strcpy or some other suitable function:
    Code:
    strcpy(ptrname[0], "Cow");
    strcpy(ptrname[1], "Parrot");
    I got it. Thanks i will try your way.

  8. #8
    Registered User
    Join Date
    Dec 2014
    Posts
    10
    Quote Originally Posted by laserlight View Post
    In other words, if you write:
    Code:
    char ptrname[35][20];
    then you cannot continue to write:
    Code:
    ptrname[0] = "Cow";
    ptrname[1] = "Parrot";
    I think you are mistaken, i am asking for the pointer array.. you r suggesting variable array.. ptrname[][]... what i want is *ptrname[][]; and i tried this 2d aray with pointer , no success

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,068
    It's not that you can't use pointers, it's just that the things you make it point to (things like "cow") are CONSTANTS.

    You need to make them point to writeable memory,
    Code:
         char *ptrname[35];
         ptrname[0] = malloc(10);
         strcpy(ptrname[0],"Cow");  // now it can be modified.
         strcat(ptrname[0],"s");
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    729
    Quote Originally Posted by waqaradil89 View Post
    I think you are mistaken, i am asking for the pointer array.. you r suggesting variable array.. ptrname[][]... what i want is *ptrname[][]; and i tried this 2d aray with pointer , no success
    Code:
    char ptrname[35][20];
    This is fine. You are defining an array of 35, 20 character arrays that can hold up to 19 characters per array, plus one byte for the '\0' nul bytes.

    The problem is with the code:
    Code:
    ptrname[0] = "Cow";
    ptrname[1] = "Parrot";
    You cannot copy strings through an assignment! You must use strcpy() to copy the strings:
    Code:
    strcpy(ptrname[0], "Cow");
    strcpy(ptrname[1], "Parrot");
    As @laserlight explained to you.

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by waqaradil89 View Post
    I think you are mistaken, i am asking for the pointer array..
    It is your usage that is mistaken.

    For your manner of using them, your pointers in the array need to be initialised so they point to (the first element of) modifiable arrays.
    Code:
        char *ptrname[35];
        char modifiable_buffer[35][20];
        for (i = 0; i < 35; ++i)
            ptrname[i] = modifiable_buffer[i];
        strcpy(ptrname[0], "Cow");        /*  this will copy characters from "Cow" into modifiable_buffer[0]   */
        strcpy(ptrname[1], "Parrot");
          /*  etc */
    It is also possible to use malloc() to initialise each element of ptrname.

    The point - which others have told you repeatedly - is that modifying something that is constant gives undefined behaviour. String literals like "Cow" are represented as const arrays. Modifying individual characters (e.g. change the 'C' to a 'c') or writing past the end (appending characters as in your example) each cause undefined behaviour. So the technique is to create a copy that can be modified, and then modify the copy.


    You happen to be picking at an anomaly in the C language. By rights, the assignment "ptrname[0] = "Cow"" should be illegal, since it discards const'ness (it allows creating a non-const pointer to something that is const). The reasons for that are tedious historical concerns but doesn't change the basic premise: if your code uses that feature, your code is broken. However, if you turn up warning levels from your compiler, it should produce a warning about that.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  12. #12
    Registered User
    Join Date
    Dec 2014
    Posts
    10
    Quote Originally Posted by Salem View Post
    It's not that you can't use pointers, it's just that the things you make it point to (things like "cow") are CONSTANTS.

    You need to make them point to writeable memory,
    Code:
         char *ptrname[35];
         ptrname[0] = malloc(10);
         strcpy(ptrname[0],"Cow");  // now it can be modified.
         strcat(ptrname[0],"s");
    I tried allocating memory but it returns error
    [Error] invalid conversion from 'void*' to 'char*' [-fpermissive]
    Last edited by waqaradil89; 12-24-2014 at 06:08 AM.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,784
    Quote Originally Posted by waqaradil89
    Invalid assignment. malloc is a void and it returns nothing where as ptrname[] is a char. So it is not possible to assign a void to char. please Check again.
    The return type of malloc is void* (i.e., pointer to void), not void. The type of ptrname[0] is char* (i.e., pointer to char), not char. A void* is convertible to char*, so there is no problem there.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Dec 2014
    Posts
    10
    @grumpy Thank you for the suggestions. Now i have enabled WARNINGS of C standards. I am a newbie.

  15. #15
    Registered User
    Join Date
    Dec 2014
    Posts
    10
    Quote Originally Posted by laserlight View Post
    The return type of malloc is void* (i.e., pointer to void), not void. The type of ptrname[0] is char* (i.e., pointer to char), not char. A void* is convertible to char*, so there is no problem there.
    HOW?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 09-19-2013, 03:51 AM
  2. strcat pointer problem
    By erasm in forum C Programming
    Replies: 15
    Last Post: 09-02-2009, 02:12 AM
  3. Pointer assignment
    By MAx12345 in forum C Programming
    Replies: 16
    Last Post: 07-10-2008, 10:42 PM
  4. Pointer Manipulation with strcat()
    By radiohead in forum C Programming
    Replies: 3
    Last Post: 03-03-2006, 07:17 AM
  5. strcat and pointer problem
    By Harman in forum C Programming
    Replies: 6
    Last Post: 05-10-2005, 05:13 PM

Tags for this Thread