Questions..

This is a discussion on Questions.. within the C Programming forums, part of the General Programming Boards category; Hello. I can't get this to work: Code: argv[1]=strcat(argv[1], ".dat"); is that legal? also, does it matter where you put ...

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    29

    Questions..

    Hello.

    I can't get this to work:
    Code:
    argv[1]=strcat(argv[1], ".dat");
    is that legal?

    also, does it matter where you put the "*" at all when it is used? Whether it be a dereference operation, function entrance, array of memory addresses, or anything else? (besides it has to be in the right order..)

    is "argv* []" the same as "argv *[]" and so on?
    is "int * pointer" the same as "int* pointer" and "int *pointer"?

    I guess thats it for now. Thanks!

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,699
    >> is that legal?

    No. The result is undefined. The string should be treated as constant.

    >> also, does it matter where you put the "*" at all when it is used?

    Whitespace is ignored between tokens in C, so you could even get away with "int*pointer"
    Code:
    bool fun(bool value)
    {
        return std::pow(std::exp(1), std::complex<float>(0, 1) 
        * std::complex<float>(std::atan(1)*(1 << (value + 2))))
        .real() > 0;
    }

  3. #3
    DESTINY BEN10's Avatar
    Join Date
    Jul 2008
    Location
    in front of my computer
    Posts
    804
    Quote Originally Posted by argv View Post
    Hello.

    I can't get this to work:
    Code:
    argv[1]=strcat(argv[1], ".dat");
    is that legal?

    also, does it matter where you put the "*" at all when it is used? Whether it be a dereference operation, function entrance, array of memory addresses, or anything else? (besides it has to be in the right order..)

    is "argv* []" the same as "argv *[]" and so on?
    is "int * pointer" the same as "int* pointer" and "int *pointer"?

    I guess thats it for now. Thanks!
    All of these have the same meaning
    Code:
    int *p;
    int* p;
    int * p;
    But it is always safer to use int *p. For eg. when sevearl pointers are to be declared simultaneously. int *p,*q,*r.
    HOPE YOU UNDERSTAND.......

    By associating with wise people you will become wise yourself
    It's fine to celebrate success but it is more important to heed the lessons of failure
    We've got to put a lot of money into changing behavior


    PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
    IDE- Microsoft Visual Studio 2008 Express Edition

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    29

    Undefined

    Quote Originally Posted by Sebastiani View Post
    >> is that legal?
    No. The result is undefined. The string should be treated as constant.
    ok, so if I want to append ".dat" to an incoming argument, what is the best way to do it?

    thank you for your (quick) reply!

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    29

    style

    Quote Originally Posted by BEN10 View Post
    But it is always safer to use int *p. For eg. when sevearl pointers are to be declared simultaneously. int *p,*q,*r.
    Sweet, I'll use that style then. thank you.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,699
    Just as you would with any other constant string - copy it.
    Code:
    bool fun(bool value)
    {
        return std::pow(std::exp(1), std::complex<float>(0, 1) 
        * std::complex<float>(std::atan(1)*(1 << (value + 2))))
        .real() > 0;
    }

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,630
    Quote Originally Posted by Sebastiani
    No. The result is undefined. The string should be treated as constant.
    No, the strings accessible via argv are modifiable. However, there is still undefined behaviour, but for a different reason: the concatenation results in ".dat" being appended, but argv[1] does not (or more accurately: might not) have any space to contain the extra 4 characters. As such, copying argv[1] to an array with sufficient space is a correct solution.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,699
    >> No, the strings accessible via argv are modifiable.

    Well of course it is, as it "belongs" to the program you are free to modify it as you wish, but the OP wanted to append to it (which would be a very bad idea for the exact reason that you pointed out). But yes, to be sure, you're explanation is more clear on the matter, but I still recommend that the practice be avoided, as it error prone (for beginners, at least).
    Code:
    bool fun(bool value)
    {
        return std::pow(std::exp(1), std::complex<float>(0, 1) 
        * std::complex<float>(std::atan(1)*(1 << (value + 2))))
        .real() > 0;
    }

  9. #9
    Registered User
    Join Date
    May 2009
    Posts
    29

    copyin

    Quote Originally Posted by Sebastiani View Post
    Just as you would with any other constant string - copy it.
    Something like this? (it seems to work)

    Code:
    char name[20];
    char ext[5];
    char fileName[25];
    strcpy(name, argv[1]);
    strcpy(ext, ".dat");
    strcat(name, ext);
    I'm very new to C, so thats why I'm asking. I want to learn it right.

    Thanks again.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,630
    Quote Originally Posted by argv
    Something like this?
    Somewhat, except that you do not know if argv[1] actually has less than 20 characters, so strcpy() risks buffer overflow. Something like this might be better:
    Code:
    if (argc > 1)
    {
        const char extension[] = ".dat";
        char *name = malloc(strlen(argv[1]) + sizeof(extension));
        if (name)
        {
            strcpy(name, argv[1]);
            strcat(name, extension);
    
            /* ... */
    
            free(name);
        }
        else
        {
            /* Report memory allocation error */
        }
    }
    else
    {
        /* Report missing command line argument */
    }
    EDIT:
    Quote Originally Posted by BEN10
    But it is always safer to use int *p. For eg. when sevearl pointers are to be declared simultaneously. int *p,*q,*r.
    It would be even safer to avoid declaring multiple pointers (or possibly even multiple variables) on the same line.

    Quote Originally Posted by argv
    Sweet, I'll use that style then.
    I tend to follow that style when writing C, but read Is ``int* p;'' right or is ``int *p;'' right?
    Last edited by laserlight; 05-30-2009 at 02:22 AM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Sebastiani View Post
    >> No, the strings accessible via argv are modifiable.

    Well of course it is, as it "belongs" to the program you are free to modify it as you wish,
    Somebody is changing their tune!
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,699
    >> char *name = malloc(strlen(argv[1]) + sizeof(extension));

    That's correct, of course, but just a reminder to the OP that the length above is equivalent to strlen(argv[1]) + strlen(extension) + 1 (to allow room for the null terminator).

    >> Somebody is changing their tune!

    Not really. My explanation certainly wasn't as concise (or strictly accurate) as laserlight's, but it wasn't exactly incorrect, either.
    Code:
    bool fun(bool value)
    {
        return std::pow(std::exp(1), std::complex<float>(0, 1) 
        * std::complex<float>(std::atan(1)*(1 << (value + 2))))
        .real() > 0;
    }

  13. #13
    Making mistakes
    Join Date
    Dec 2008
    Posts
    476
    No. laserlights solution is better because:
    1 - sizeof extension includes the NUL character
    2 - sizeof extension is a compile-time constant. (No strlen overhead).

    And I use "int *pointer". I even put the '*' on the right side in casts or type names, meaning "sizeof(char **)" or "*(int *)pointer" because I like it and It is 0.1% more clear.

  14. #14
    Registered User
    Join Date
    May 2009
    Posts
    29

    ...

    Quote Originally Posted by laserlight View Post
    Somewhat, except that you do not know if argv[1] actually has less than 20 characters, so strcpy() risks buffer overflow. Something like this might be better:
    Code:
    if (argc > 1)
    {
        const char extension[] = ".dat";
        char *name = malloc(strlen(argv[1]) + sizeof(extension));
        if (name)
        {
            strcpy(name, argv[1]);
            strcat(name, extension);
    
            /* ... */
    
            free(name);
        }
        else
        {
            /* Report memory allocation error */
        }
    }
    else
    {
        /* Report missing command line argument */
    }
    Ok, haven't gotten into the malloc command much yet, thats next quarter. If I throw that in, my teacher will know I stole it. haha

    by the way, is: "char *name" the same as "char name[]";

    Quote Originally Posted by laserlight View Post
    EDIT:

    It would be even safer to avoid declaring multiple pointers (or possibly even multiple variables) on the same line.


    I tend to follow that style when writing C, but read Is ``int* p;'' right or is ``int *p;'' right?

    I dunno, but I like 'int* p' for some wierd reason. I guess as long as your consistent, it doesn't matter.
    Last edited by argv; 05-30-2009 at 11:35 AM.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,630
    Quote Originally Posted by argv
    by the way, is: "char *name" the same as "char name[]";
    In this context, no. The former declares name as a pointer to char, the latter declares name as an array of char with the size determined by the initialiser (in this case the string literal ".dat", hence a size of 5).

    EDIT:
    Quote Originally Posted by argv
    Ok, haven't gotten into the malloc command much yet, thats next quarter.
    If you want to stick with your original working solution and yet avoid buffer overflow, you could use:
    Code:
    char name[25];
    strncpy(name, argv[1], 20);
    name[20] = '\0';
    strcat(name, ".dat");
    I am assuming that you want to limit the name without extension to 20 characters.
    Last edited by laserlight; 05-30-2009 at 11:50 AM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. questions....so many questions about random numbers....
    By face_master in forum C++ Programming
    Replies: 2
    Last Post: 07-30-2009, 08:47 AM
  2. A very long list of questions... maybe to long...
    By Ravens'sWrath in forum C Programming
    Replies: 16
    Last Post: 05-16-2007, 05:36 AM
  3. Several Questions, main one is about protected memory
    By Tron 9000 in forum C Programming
    Replies: 3
    Last Post: 06-02-2005, 07:42 AM
  4. Trivial questions - what to do?
    By Aerie in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 12-26-2004, 08:44 AM
  5. questions questions questions.....
    By mfc2themax in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 08-14-2001, 07:22 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21