Shifting string in an array

S

Surya

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;
}
}
 
M

Malcolm McLean

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.
 
S

Surya

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..
 
E

Eric Sosman

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>


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.
 
K

Keith Thompson

Surya said:
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.
 
S

Shao Miller

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;
}
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top