Shifting string in an array

Discussion in 'C Programming' started by Surya, Jan 28, 2013.

  1. Surya

    Surya Guest

    Lets say I have string...

    s = " hello"
    I want to shift "hello" to left side by 1 unit. which turns s = "hello".
    Here is my code. but its not working. Can anyone look into it and let me know where I am going wrong?

    # include <stdio.h>
    # include <string.h>
    main()
    {
    char *s = " surya";
    char *shift(char *, int);

    shift(s+1,-1);
    printf("%s", s);
    }

    char *shift (char *str, int units)
    {
    if (units < 0)
    {
    for (; *str != '\0'; str++){
    *(str + units) = *str;
    }
    return str;
    }
    }
    Surya, Jan 28, 2013
    #1
    1. Advertising

  2. On Monday, January 28, 2013 4:30:50 PM UTC, Surya wrote:
    > Lets say I have string...
    >
    >
    >
    > s = " hello"
    >
    > I want to shift "hello" to left side by 1 unit. which turns s = "hello".
    >
    > Here is my code. but its not working. Can anyone look into it and let me know where I am going wrong?
    >
    >
    >
    > # include <stdio.h>
    >
    > # include <string.h>
    >
    > main()
    >
    > {
    >
    > char *s = " surya";
    >
    > char *shift(char *, int);
    >
    >
    >
    > shift(s+1,-1);
    >
    > printf("%s", s);
    >
    > }
    >
    >
    >
    > char *shift (char *str, int units)
    >
    > {
    >
    > if (units < 0)
    >
    > {
    >
    > for (; *str != '\0'; str++){
    >
    > *(str + units) = *str;
    >
    > }
    >
    > return str;
    >
    > }
    >
    > }


    You forgot the terminating nul.
    Malcolm McLean, Jan 28, 2013
    #2
    1. Advertising

  3. Surya

    Surya Guest

    On Monday, January 28, 2013 10:05:57 PM UTC+5:30, Malcolm McLean wrote:
    > On Monday, January 28, 2013 4:30:50 PM UTC, Surya wrote:
    >
    > > Lets say I have string...

    >
    > >

    >
    > >

    >
    > >

    >
    > > s = " hello"

    >
    > >

    >
    > > I want to shift "hello" to left side by 1 unit. which turns s = "hello".

    >
    > >

    >
    > > Here is my code. but its not working. Can anyone look into it and let me know where I am going wrong?

    >
    > >

    >
    > >

    >
    > >

    >
    > > # include <stdio.h>

    >
    > >

    >
    > > # include <string.h>

    >
    > >

    >
    > > main()

    >
    > >

    >
    > > {

    >
    > >

    >
    > > char *s = " surya";

    >
    > >

    >
    > > char *shift(char *, int);

    >
    > >

    >
    > >

    >
    > >

    >
    > > shift(s+1,-1);

    >
    > >

    >
    > > printf("%s", s);

    >
    > >

    >
    > > }

    >
    > >

    >
    > >

    >
    > >

    >
    > > char *shift (char *str, int units)

    >
    > >

    >
    > > {

    >
    > >

    >
    > > if (units < 0)

    >
    > >

    >
    > > {

    >
    > >

    >
    > > for (; *str != '\0'; str++){

    >
    > >

    >
    > > *(str + units) = *str;

    >
    > >

    >
    > > }

    >
    > >

    >
    > > return str;

    >
    > >

    >
    > > }

    >
    > >

    >
    > > }

    >
    >
    >
    > You forgot the terminating nul.


    Can you give the code?
    Surya, Jan 28, 2013
    #3
  4. Surya

    Surya Guest

    On Monday, January 28, 2013 10:13:04 PM UTC+5:30, Surya wrote:
    > On Monday, January 28, 2013 10:05:57 PM UTC+5:30, Malcolm McLean wrote:
    >
    > > On Monday, January 28, 2013 4:30:50 PM UTC, Surya wrote:

    >
    > >

    >
    > > > Lets say I have string...

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > s = " hello"

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > I want to shift "hello" to left side by 1 unit. which turns s = "hello".

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > Here is my code. but its not working. Can anyone look into it and let me know where I am going wrong?

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > # include <stdio.h>

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > # include <string.h>

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > main()

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > {

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > char *s = " surya";

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > char *shift(char *, int);

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > shift(s+1,-1);

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > printf("%s", s);

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > }

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > char *shift (char *str, int units)

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > {

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > if (units < 0)

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > {

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > for (; *str != '\0'; str++){

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > *(str + units) = *str;

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > }

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > return str;

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > }

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > }

    >
    > >

    >
    > >

    >
    > >

    >
    > > You forgot the terminating nul.

    >
    >
    >
    > Can you give the code?


    char *shift (char *str, int units)
    {
    if (units < 0)
    {
    for (; *str != '\0'; str++)
    *(str + units) = *str;
    *(str + units) = '\0'; // Terminate with \0
    return str;
    }

    }

    I could do this way..but the program is not even working.. OS is terminating it..
    Surya, Jan 28, 2013
    #4
  5. On Jan 28, 10:46 am, Surya <> wrote:
    > On Monday, January 28, 2013 10:13:04 PM UTC+5:30, Surya wrote:
    > > On Monday, January 28, 2013 10:05:57 PM UTC+5:30, Malcolm McLean wrote:
    > > > On Monday, January 28, 2013 4:30:50 PM UTC, Surya wrote:

    >

    (...)
    > > > >  char *s = " surya";


    Try

    char s[] = " surya";
    Anand Hariharan, Jan 28, 2013
    #5
  6. Surya

    Surya Guest

    On Monday, January 28, 2013 10:29:02 PM UTC+5:30, Anand Hariharan wrote:
    > On Jan 28, 10:46 am, Surya <> wrote:
    >
    > > On Monday, January 28, 2013 10:13:04 PM UTC+5:30, Surya wrote:

    >
    > > > On Monday, January 28, 2013 10:05:57 PM UTC+5:30, Malcolm McLean wrote:

    >
    > > > > On Monday, January 28, 2013 4:30:50 PM UTC, Surya wrote:

    >
    > >

    >
    > (...)
    >
    > > > > >  char *s = " surya";

    >
    >
    >
    > Try
    >
    >
    >
    > char s[] = " surya";


    yeah! got it... I am operating on string literal which is illegal. Oops.
    Surya, Jan 28, 2013
    #6
  7. Surya

    Eric Sosman Guest

    On 1/28/2013 11:30 AM, Surya wrote:
    > Lets say I have string...
    >
    > s = " hello"
    > I want to shift "hello" to left side by 1 unit. which turns s = "hello".
    > Here is my code. but its not working. Can anyone look into it and let me know where I am going wrong?


    "It's not working" is a poor description of a problem. It forces
    us to guess about the nature of the failure: Does the compiler reject
    the code, does it crash when it runs, does it run to completion but
    produce unexpected results (what are they, and what did you expect), ...
    By analogy, you have sent a message to your doctor saying "It hurts,"
    but have not told him whether the pain is in your ear or your ankle.

    I'll point out some potential problems with your code, but I have
    no way of knowing whether any of these is the one bothering you. Next
    time, be more informative.

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


    You don't use anything from <string.h>, so why #include it?

    > main()


    int main(void)

    > {
    > char *s = " surya";


    Okay, `s' points to the start of an anonymous array of the
    seven characters ' ', 's', 'u', 'r', 'y', 'a', and '\0'. The
    fact that the array is not `const' is a historical accident: If
    you try to modify the array you invoke undefined behavior.

    To get an array of characters that you *can* modify, use

    char s[] = " surya";

    > char *shift(char *, int);
    >
    > shift(s+1,-1);
    > printf("%s", s);


    If your program's final line of output has no '\n' at the
    end, you may or may not ever see it.

    As mentioned above, the main() function must return an
    `int' value indicating whether the program succeeded or failed,
    so there should be a `return some_value;' statement here. When
    you "fall off the end" there's no telling what sort of status
    your program might report. (Pedantry alert: Recent versions of
    the C Standard define "falling off the end" of main() to be
    equivalent to ending with `return 0;' -- but those same versions
    also forbid the plain `main()' definition you used earlier, so
    either way you're in trouble.)

    > }
    >
    > char *shift (char *str, int units)


    You never use the value returned by the function, so it's
    not clear why you return one at all.

    > {
    > if (units < 0)
    > {
    > for (; *str != '\0'; str++){
    > *(str + units) = *str;
    > }


    As explained above, it's an error to try to modify the string
    your program is actually using. But if you were using a modifiable
    string instead, this loop would be equivalent to this sequence of
    individual assignments (imagine that a variable `array' points to
    the original target of `str' throughout):

    array[-1] = array[0]; /* ' ' <- 's' */
    array[0] = array[1]; /* 's' <- 'u' */
    array[1] = array[2]; /* 'u' <- 'r' */
    array[3] = array[4]; /* 'r' <- 'y' */
    array[4] = array[5]; /* 'y' <- 'a' */

    At this point the assignments stop, because `str' now points at
    the final '\0'. The array now holds 'u','r','y','a','a','\0'
    and there is an 's' just before it, in the [-1] position. See
    the two 'a's? Do you see why the second one is still there?

    > return str;


    The returned value isn't used. If you were to use it, you'd
    find that it points at the '\0' that terminates the string.

    > }


    ... and what value does the function return if `units' is
    zero or positive? You "fall off the end," and if the caller
    tries to use the value you failed to return, you get undefined
    behavior again.

    > }
    >


    Next time, explain your problem more fully.

    --
    Eric Sosman
    d
    Eric Sosman, Jan 28, 2013
    #7
  8. Surya <> writes:
    > Lets say I have string...
    >
    > s = " hello"
    > I want to shift "hello" to left side by 1 unit. which turns s = "hello".
    > Here is my code. but its not working. Can anyone look into it and let me know where I am going wrong?
    >
    > # include <stdio.h>
    > # include <string.h>
    > main()
    > {
    > char *s = " surya";
    > char *shift(char *, int);
    >
    > shift(s+1,-1);
    > printf("%s", s);
    > }
    >
    > char *shift (char *str, int units)
    > {
    > if (units < 0)
    > {
    > for (; *str != '\0'; str++){
    > *(str + units) = *str;
    > }
    > return str;
    > }
    > }


    Some issues that probably aren't relevant to the symptoms you're seeing:

    It's perfectly legal to declare (*not* define) a function inside another
    function, but IMHO it's rarely a good idea. When the compiler sees the
    call to your shift function, it needs to have already seen a valid
    declaration of that function; there are several ways you could make that
    happen.

    Another way is to declare the function at file scope -- and IMHO you
    might as well include the parameter names in that delaration:

    char *shift(char *str, int units);

    int main(void) {
    /* ... */
    }

    char *shift(char *str, int units) {
    /* ... */
    }

    Or you can put the entire definition of shift() above the definition of
    main(), and leave out the separate declaration:

    char *shift(char *str, int units) {
    /* ... */
    }

    int main(void) {
    /* ... */
    }

    The latter forces you to reorder your function definitions, and perhaps
    you'd rather define main first.

    Having a block-scope declaration of shift is, as I said, perfectly
    legal, but it restricts the visibility of the declaration (what if you
    want to call shift from some other function?).

    For larger programs, you'd likely put the definition of shift() into a
    separately compiled source file, say "shift.c", and its declaration into
    a header file, say "shift.h".

    Also, if you use

    printf("%s\n", s);

    it will, on some systems, make it more likely that you'll see your
    program's output and that it won't be printed together with your next
    shell prompt. You could also use

    puts(s);

    which automatically appends a newline.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 28, 2013
    #8
  9. Surya

    Shao Miller Guest

    On 1/28/2013 11:30, Surya wrote:
    > Lets say I have string...
    >
    > s = " hello"
    > I want to shift "hello" to left side by 1 unit. which turns s = "hello".
    > Here is my code. but its not working. Can anyone look into it and let me know where I am going wrong?
    >


    It is good that you identified the cause of your problem: Attempting to
    modify a string literal's array.

    You can, in general, shift to the left with 'memmove':

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

    int main(void) {
    char s[] = " hello";
    size_t shift_count = 1;

    memmove(s, s + shift_count, sizeof s - shift_count);
    printf("%s, world!\n", s);
    return 0;
    }

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
    Shao Miller, Jan 28, 2013
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. walala
    Replies:
    3
    Views:
    5,327
    Brent Hayhoe
    Nov 21, 2003
  2. Stefan Duenser

    Basic shifting question

    Stefan Duenser, Dec 7, 2004, in forum: VHDL
    Replies:
    4
    Views:
    440
    Stefan Duenser
    Dec 8, 2004
  3. Replies:
    1
    Views:
    463
  4. Ken

    array shifting

    Ken, Dec 16, 2004, in forum: C++
    Replies:
    9
    Views:
    484
    Jonathan Mcdougall
    Dec 20, 2004
  5. go6ko01

    Shifting Numbers Inside Array

    go6ko01, Nov 20, 2009, in forum: C Programming
    Replies:
    0
    Views:
    321
    go6ko01
    Nov 20, 2009
Loading...

Share This Page