Jump to content

Need help manipulating strings in C.

duckwithanokhat

So I want to remove the first character of a char *. Stack overflow gave me the solution that:

 

//str1 is the original

char *str2 = str1 + 1;

 

The thing is this works, but every time I change str2, str1 also changes. So is there a way to not change remove the first char without changing str1?

Link to comment
Share on other sites

Link to post
Share on other sites

That's because you're just making str2 a pointer to the second character of str1.  You want to give it its own array.  Do you know how big the maximum length will be?  If you do, then the easiest way is to just copy it over.

char str2[20];
strncpy(str2, str1 + 1 , sizeof(str2) - 1);

Change 20 to whatever the maximum length is.  The use of strncpy instead of strcpy is to prevent any overflows.  You could also use

char str2[20];
strncpy(str2, str1 + 1 , 20);

However, in that situation you'd have to remember to change both 20's.  It's not a big deal in small code, but when you start writing massive programs, it lets you simultaneously change all the values.

Make sure to quote or tag me (@JoostinOnline) or I won't see your response!

PSU Tier List  |  The Real Reason Delidding Improves Temperatures"2K" does not mean 2560×1440 

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, JoostinOnline said:

That's because you're just making str2 a pointer to the second character of str1.  You want to make it its own array.  Do you know how big the maximum length will be?  If you do, then the easiest way is to just copy it over.


char str2[20];
strncpy(str2, str1 + 1 , sizeof(str2) - 1);

Change 20 to whatever the maximum length is.  The use of strncpy instead of strcpy is to prevent any overflows.  You could also use


char str2[20];
strncpy(str2, str1 + 1 , 20);

However, in that situation you'd have to remember to change both 20's.  It's not a big deal in small code, but when you start writing massive programs, it lets you simultaneously change all the values.

The thing is str1 is also a char * because it's actually a string from strtok() (if you know what that is), would it still work?

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, duckwithanokhat said:

The thing is str1 is also a char * because it's actually a string from strtok() (if you know what that is), would it still work?

Yes.  str2 is still a pointer.  It's just pointing to its own set of data.  In your code, both str1 and str2 were pointing to the same part of the memory (except str2 started with the second character).

Make sure to quote or tag me (@JoostinOnline) or I won't see your response!

PSU Tier List  |  The Real Reason Delidding Improves Temperatures"2K" does not mean 2560×1440 

Link to comment
Share on other sites

Link to post
Share on other sites

9 minutes ago, JoostinOnline said:

Yes.  str2 is still a pointer.  It's just pointing to its own set of data.  In your code, both str1 and str2 were pointing to the same part of the memory (except str2 started with the second character).

Thank you, it works!

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, duckwithanokhat said:

Thank you, it works!

Just make sure that 20 is big enough.  If str1 is "Yankee doodle went to town", then str2 will only be "ankoo doodle went to", because there is a 20 character limit.

Make sure to quote or tag me (@JoostinOnline) or I won't see your response!

PSU Tier List  |  The Real Reason Delidding Improves Temperatures"2K" does not mean 2560×1440 

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, JoostinOnline said:

Just make sure that 20 is big enough.  If str1 is "Yankee doodle went to town", then str2 will only be "ankoo doodle went to", because there is a 20 character limit.

Yea I changed it to 500 :) 

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, duckwithanokhat said:

Yea I changed it to 500 :) 

I'm probably getting annoying at this point, but you also don't want to make it too high.  When you set it to 500, you're using up 501 bytes of RAM.  Just food for thought.

Make sure to quote or tag me (@JoostinOnline) or I won't see your response!

PSU Tier List  |  The Real Reason Delidding Improves Temperatures"2K" does not mean 2560×1440 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, JoostinOnline said:

I'm probably getting annoying at this point, but you also don't want to make it too high.  When you set it to 500, you're using up 501 bytes of RAM.  Just food for thought.

Nah your fine, but I need 500 because the program I'm writing translates English sentences into pig Latin.

Link to comment
Share on other sites

Link to post
Share on other sites

You could just work with pointers and strncpy()/strncat() so you won't have to set any buffers explicitly.

Write in C.

Link to comment
Share on other sites

Link to post
Share on other sites

17 minutes ago, Dat Guy said:

You could just work with pointers and strncpy()/strncat() so you won't have to set any buffers explicitly.

Wouldn't you need to use malloc each time though?

Make sure to quote or tag me (@JoostinOnline) or I won't see your response!

PSU Tier List  |  The Real Reason Delidding Improves Temperatures"2K" does not mean 2560×1440 

Link to comment
Share on other sites

Link to post
Share on other sites

That would be one way to do it - still more flexible than fixed char[] buffers.

Write in C.

Link to comment
Share on other sites

Link to post
Share on other sites

7 minutes ago, Dat Guy said:

That would be one way to do it - still more flexible than fixed char[] buffers.

It's also very inefficient.  It's like the slowest command there is built into C.  You'll also have to add strlen into the mix.

Make sure to quote or tag me (@JoostinOnline) or I won't see your response!

PSU Tier List  |  The Real Reason Delidding Improves Temperatures"2K" does not mean 2560×1440 

Link to comment
Share on other sites

Link to post
Share on other sites

15 minutes ago, Dat Guy said:

strlen() would be a bad idea. Use sizeof().

sizeof wouldn't work.  It's an operator that converts the size of a variable into an integer before a program when a program is compiled.  It's not executable code.

Make sure to quote or tag me (@JoostinOnline) or I won't see your response!

PSU Tier List  |  The Real Reason Delidding Improves Temperatures"2K" does not mean 2560×1440 

Link to comment
Share on other sites

Link to post
Share on other sites

Depending on what you want to achieve, sizeof() might work rather well unless you work with runtime-defined strings (which is unclear from the OP's original question).

Write in C.

Link to comment
Share on other sites

Link to post
Share on other sites

Perhaps relevant:

If you want to go the malloc + copy route in order to copy strings of unknown length without allocating too much memory on the stack. (Because, how much do you really need to be sure ? A string can be longer then 500 characters)...

The C function strdup does the malloc and copy in one. Just remember to free the copy when you're done with it.

Link to comment
Share on other sites

Link to post
Share on other sites

57 minutes ago, JoostinOnline said:

sizeof wouldn't work.  It's an operator that converts the size of a variable into an integer before a program when a program is compiled.  It's not executable code.

Yes it would.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
  
#define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0])
  
int main()
{
    char first[] = "Hello, World";
    char *second = (char *)calloc(ARRAY_SIZE(first), sizeof(char));
    strncpy(second, first, ARRAY_SIZE(first));
    printf("first = %s, second = %s\n", first, second);
    free(second); //Make sure to free all calloc'd or malloc'd memory
}
pinguinsan@Z170A-Titanium-PC:~$ ./test 
first = Hello, World, second = Hello, World

 

Link to comment
Share on other sites

Link to post
Share on other sites

5 minutes ago, Unimportant said:

The C function strdup does the malloc and copy in one. 

Note that strdup() is not a part of the C standard, it might or might not be implemented in a similar way by any C compiler.

Write in C.

Link to comment
Share on other sites

Link to post
Share on other sites

15 minutes ago, Pinguinsan said:

Yes it would.


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
  
#define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0])
  
int main()
{
    char first[] = "Hello, World";
    char *second = (char *)calloc(ARRAY_SIZE(first), sizeof(char));
    strncpy(second, first, ARRAY_SIZE(first));
    printf("first = %s, second = %s\n", first, second);
    free(second); //Make sure to free all calloc'd or malloc'd memory
}

pinguinsan@Z170A-Titanium-PC:~$ ./test 
first = Hello, World, second = Hello, World

 

But the OP only said "str1 is the original". So you can't be sure it's an array, it might be a pointer...

void Foo(char* str1)
{
	//ARRAY_SIZE(str1) == sizeof(void *) / sizeof(str1[0])  
}

Simplest is to use strlen(), that should always work except is the string is not 0-terminated, but if it is not, all other string functions like strncpy() will not work eighter.

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, Pinguinsan said:

Yes it would.


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
  
#define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0])
  
int main()
{
    char first[] = "Hello, World";
    char *second = (char *)calloc(ARRAY_SIZE(first), sizeof(char));
    strncpy(second, first, ARRAY_SIZE(first));
    printf("first = %s, second = %s\n", first, second);
    free(second); //Make sure to free all calloc'd or malloc'd memory
}

pinguinsan@Z170A-Titanium-PC:~$ ./test 
first = Hello, World, second = Hello, World

 

In your version, the length of "first" is already known.  If it's an entry by the user (which it probably is, since he said str1 changes), then sizeof won't work.

Make sure to quote or tag me (@JoostinOnline) or I won't see your response!

PSU Tier List  |  The Real Reason Delidding Improves Temperatures"2K" does not mean 2560×1440 

Link to comment
Share on other sites

Link to post
Share on other sites

@Unimportant str1 is a char * that receives it's string from strtok. An example would be like if the user inputted "Hello world". I would use strtok() to remove the spaces and str1 would get "Hello" and then "World".

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×