creating a variable from constant

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Robert

    creating a variable from constant

    Hi, I am kinda new to c and i've encountered a problem with
    program because i need to change a constant. I ofcourse don't
    want to change a constant so is there any way to convert a
    constant to a variable? I've tried something with malloc but
    it didn't work for me. Here's what i tried:

    char *url;
    char *filename;
    char *tmpstring;
    url = strtok(header, " ");
    url = strtok(NULL, " ");
    puts (url);
    //tmpstring = (char *)malloc(sizeof (SERVER_ROOT)*s trlen(SERVER_RO OT));
    tmpstring = (char *)malloc(1000);
    tmpstring = SERVER_ROOT;
    //strcat (url, SERVER_ROOT);
    filename = strcat(tmpstrin g, url);
    puts (url);

    as you can see i am trieing to combine SERVER_ROOT and url to
    get something like /var/www/html/news.html where SERVER_ROOT
    is /var/www/html and url = /news.html

    Can anyone please help me?
    Thanks in advance,

    Robert
  • Ben Pfaff

    #2
    Re: creating a variable from constant

    Robert <R.Mens@hetnet. nl> writes:
    [color=blue]
    > Hi, I am kinda new to c and i've encountered a problem with
    > program because i need to change a constant. I ofcourse don't
    > want to change a constant so is there any way to convert a
    > constant to a variable? I've tried something with malloc but
    > it didn't work for me. Here's what i tried:
    >
    > char *url;
    > char *filename;
    > char *tmpstring;
    > url = strtok(header, " ");
    > url = strtok(NULL, " ");[/color]

    strtok() has at least these problems:

    * It merges adjacent delimiters. If you use a comma as
    your delimiter, then "a,,b,c" is three tokens, not
    four. This is often the wrong thing to do. In fact,
    it is only the right thing to do, in my experience,
    when the delimiter set is limited to white space.

    * The identity of the delimiter is lost, because it is
    changed to a null terminator.

    * It modifies the string that it tokenizes. This is bad
    because it forces you to make a copy of the string if
    you want to use it later. It also means that you can't
    tokenize a string literal with it; this is not
    necessarily something you'd want to do all the time but
    it is surprising.

    * It can only be used once at a time. If a sequence of
    strtok() calls is ongoing and another one is started,
    the state of the first one is lost. This isn't a
    problem for small programs but it is easy to lose track
    of such things in hierarchies of nested functions in
    large programs. In other words, strtok() breaks
    encapsulation.
    [color=blue]
    > puts (url);
    > //tmpstring = (char *)malloc(sizeof (SERVER_ROOT)*s trlen(SERVER_RO OT));[/color]

    When calling malloc(), I recommend using the sizeof operator on
    the object you are allocating, not on the type. For instance,
    *don't* write this:

    int *x = malloc (sizeof (int) * 128); /* Don't do this! */

    Instead, write it this way:

    int *x = malloc (sizeof *x * 128);

    There's a few reasons to do it this way:

    * If you ever change the type that `x' points to, it's not
    necessary to change the malloc() call as well.

    This is more of a problem in a large program, but it's still
    convenient in a small one.

    * Taking the size of an object makes writing the statement
    less error-prone. You can verify that the sizeof syntax is
    correct without having to look at the declaration.
    I don't recommend casting the return value of malloc():

    * The cast is not required in ANSI C.

    * Casting its return value can mask a failure to #include
    <stdlib.h>, which leads to undefined behavior.

    * If you cast to the wrong type by accident, odd failures can
    result.

    Also, I don't understand why you'd multiply those two values.
    What is SERVER_ROOT?
    [color=blue]
    > tmpstring = (char *)malloc(1000);
    > tmpstring = SERVER_ROOT;[/color]

    Here's a real problem. You malloc() 1000 bytes of memory, and
    then you just go ahead and throw it away. You probably want to
    use strcpy() instead of assignment in the second statement there.
    [color=blue]
    > //strcat (url, SERVER_ROOT);[/color]

    strcat() only works on strings, and before you put any data into
    malloc()'d memory, it's not a string. You could use strcat() if
    you first assigned '\0' to the first byte malloc()'d,
    e.g. tmpstring[0] = '\0';
    [color=blue]
    > filename = strcat(tmpstrin g, url);
    > puts (url);
    >
    > as you can see i am trieing to combine SERVER_ROOT and url to
    > get something like /var/www/html/news.html where SERVER_ROOT
    > is /var/www/html and url = /news.html[/color]

    You can do that in a single function call with sprintf():
    sprintf(tmpstri ng, "%s%s", SERVER_ROOT, url);
    --
    "I don't have C&V for that handy, but I've got Dan Pop."
    --E. Gibbons

    Comment

    • Robert

      #3
      Re: creating a variable from constant

      Ben Pfaff wrote:
      [color=blue]
      > Robert <R.Mens@hetnet. nl> writes:
      >[color=green]
      >> Hi, I am kinda new to c and i've encountered a problem with
      >> program because i need to change a constant. I ofcourse don't
      >> want to change a constant so is there any way to convert a
      >> constant to a variable? I've tried something with malloc but
      >> it didn't work for me. Here's what i tried:
      >>
      >> char *url;
      >> char *filename;
      >> char *tmpstring;
      >> url = strtok(header, " ");
      >> url = strtok(NULL, " ");[/color]
      >
      > strtok() has at least these problems:
      >
      > * It merges adjacent delimiters. If you use a comma as
      > your delimiter, then "a,,b,c" is three tokens, not
      > four. This is often the wrong thing to do. In fact,
      > it is only the right thing to do, in my experience,
      > when the delimiter set is limited to white space.
      >
      > * The identity of the delimiter is lost, because it is
      > changed to a null terminator.
      >
      > * It modifies the string that it tokenizes. This is bad
      > because it forces you to make a copy of the string if
      > you want to use it later. It also means that you can't
      > tokenize a string literal with it; this is not
      > necessarily something you'd want to do all the time but
      > it is surprising.
      >
      > * It can only be used once at a time. If a sequence of
      > strtok() calls is ongoing and another one is started,
      > the state of the first one is lost. This isn't a
      > problem for small programs but it is easy to lose track
      > of such things in hierarchies of nested functions in
      > large programs. In other words, strtok() breaks
      > encapsulation.
      >[color=green]
      >> puts (url);
      >> //tmpstring = (char *)malloc(sizeof (SERVER_ROOT)*s trlen(SERVER_RO OT));[/color]
      >
      > When calling malloc(), I recommend using the sizeof operator on
      > the object you are allocating, not on the type. For instance,
      > *don't* write this:
      >
      > int *x = malloc (sizeof (int) * 128); /* Don't do this! */
      >
      > Instead, write it this way:
      >
      > int *x = malloc (sizeof *x * 128);
      >
      > There's a few reasons to do it this way:
      >
      > * If you ever change the type that `x' points to, it's not
      > necessary to change the malloc() call as well.
      >
      > This is more of a problem in a large program, but it's still
      > convenient in a small one.
      >
      > * Taking the size of an object makes writing the statement
      > less error-prone. You can verify that the sizeof syntax is
      > correct without having to look at the declaration.
      > I don't recommend casting the return value of malloc():
      >
      > * The cast is not required in ANSI C.
      >
      > * Casting its return value can mask a failure to #include
      > <stdlib.h>, which leads to undefined behavior.
      >
      > * If you cast to the wrong type by accident, odd failures can
      > result.
      >
      > Also, I don't understand why you'd multiply those two values.
      > What is SERVER_ROOT?
      >[color=green]
      >> tmpstring = (char *)malloc(1000);
      >> tmpstring = SERVER_ROOT;[/color]
      >
      > Here's a real problem. You malloc() 1000 bytes of memory, and
      > then you just go ahead and throw it away. You probably want to
      > use strcpy() instead of assignment in the second statement there.
      >[color=green]
      >> //strcat (url, SERVER_ROOT);[/color]
      >
      > strcat() only works on strings, and before you put any data into
      > malloc()'d memory, it's not a string. You could use strcat() if
      > you first assigned '\0' to the first byte malloc()'d,
      > e.g. tmpstring[0] = '\0';
      >[color=green]
      >> filename = strcat(tmpstrin g, url);
      >> puts (url);
      >>
      >> as you can see i am trieing to combine SERVER_ROOT and url to
      >> get something like /var/www/html/news.html where SERVER_ROOT
      >> is /var/www/html and url = /news.html[/color]
      >
      > You can do that in a single function call with sprintf():
      > sprintf(tmpstri ng, "%s%s", SERVER_ROOT, url);[/color]

      Thanks, i got it working now after a few experiments.
      It's now something like:

      char *url;
      char *filename;
      char *tmpstring;
      url = strtok(header, " ");
      url = strtok(NULL, " ");
      puts (url);
      //tmpstring = (char *)malloc(sizeof (SERVER_ROOT)*s trlen(SERVER_RO OT));
      tmpstring = (char *)malloc(1000);
      tmpstring[0] = "\0";
      strcpy (tmpstring, SERVER_ROOT);
      strcat (tmpstring, url);
      //filename = strcat(tmpstrin g, url);

      //sprintf(tmpstri ng,"%s%u", SERVER_ROOT, url);

      puts (tmpstring);

      btw, as you can see i was to lazy to change the malloc really
      before i posted this, i am going to change that ofcourse.

      Once again thanks.
      Robert

      Comment

      • Ben Pfaff

        #4
        Re: creating a variable from constant

        Robert <R.Mens@hetnet. nl> writes:
        [color=blue]
        > tmpstring = (char *)malloc(1000);
        > tmpstring[0] = "\0";
        > strcpy (tmpstring, SERVER_ROOT);
        > strcat (tmpstring, url);[/color]

        If you use strcpy(), you don't need to initialize tmpstring[0].
        strcpy() doesn't assume that its destination is a string.
        --
        "I don't have C&V for that handy, but I've got Dan Pop."
        --E. Gibbons

        Comment

        Working...