How do I convert char pointer into a string?
I know it's a pointer to a string, but I don't want a pointer.
For example:
char* token;
char strings[50];
char strings[50] is a char string.
What is easiest way to turn *token into a string?
mbtowc turns *token in a single char, I don't want single char. Entire String.
The sad fact is that most C string library functions like strcpy(), strncpy() and memcpy() are somewhat lacking in terms of safely, reliably, and/or simply copying a C string into a char array.
Here's one way to do it:
size_t len = strlen(token);
if (len < sizeof(strings)) {
memcpy(strings, token, len); // assumes token doesn't point inside strings, else use memmove()
strings[len] = '\0';
} else {
// input string was too long, handle the error somehow
}
As you can imagine, many projects implemented in C will define a few functions to handle C strings efficiently in whatever way they need, with appropriate error handling.
/*until C99*/
char *token = "test";
char strings[50];
/* copy to sized buffer: */
strncpy ( strings, token, sizeof(strings) );
strings[sizeof(strings) - 1] = 0;
/*since C11*/
char *token = "test";
char strings[50];
/* returns zero on success, returns non-zero on error.*/
int r1 = strncpy_s(strings, sizeof(strings), token, strlen(token));
/*use strlen_s if not sure whether token is not null poiter*/
Related
I have uni project, I need to check if the syntax is right. I get pointer to a string, and check if the first token acceptable. In case it's OK, i move forward. But in case it's not OK, i need to print what is wrong.
What i did is to create a buffer since i can't change the original string.
After that i use strtok to cut the buffer, and look if the token i got is acceptable.
char *str = "sz = 12345";
printf("The check of MACRO: %d\n", isMacro(str));
int isMacro(char *str)
{
char buf = NULL;
char *token;
strcpy(&buf,str);
token = strtok(&buf," ");
printf("You here, value token is %s\n",token);
}
I expected that printf would print the 'sz' but it prints:
You here, value str is sz<▒R
char buf = NULL;
This is a type error. buf is a single character, but NULL is a pointer value. You can't store a pointer in a char.
strcpy(&buf,str);
This code has undefined behavior (unless str happens to be an empty string). buf is not a buffer, it is a single char, so it does not have room to store a whole string.
If you want to make a copy of a string, you need to allocate enough memory for all of its characters:
You could use strdup (which is in POSIX, but not standard C):
char *buf = strdup(str);
if (!buf) {
... handle error ...
}
...
free(buf);
You could replicate strdup manually:
char *buf = malloc(strlen(str) + 1);
if (!buf) {
... handle error ...
}
strcpy(buf, str);
...
free(buf);
You could use a variable-length array (but you're limited by the size of your stack and you have no way to check for errors):
char buf[strlen(str) + 1];
strcpy(buf, str);
...
buf is a single char instead of a pointer to a char. In fact, if you're planning to do strcpy to copy a string to it, you need to allocate memory first using malloc. Instead I'd suggest you to use a function like strdup instead of strcpy to create a copy of the original string to modify it using strtok. Remember to free the strduped string later.
Something like this.
int isMacro(char *str)
{
char *buf = NULL;
char *token;
buf = strdup(str);
token = strtok(buf," ");
printf("You here, value of token is %s\n",token);
free(buf);
}
As per this description, strtok() delimitate a string into tokens by the delimiter given, returns a pointer to the first token found in the string. All subsequent tokens need to be traversed via a loop, like the example code given in the link.
Does each token auto terminate with NULL? i.e. can I simply assign each token to a variable and use it or does it need strncpy() to be copied to an allocated space?
For example, would this be valid?
char str[80] = "This is - www.tutorialspoint.com - website";
const char s[2] = "-";
char *token;
char *test[4];
int test_count = 0;
memset(test, 0x00, 4);
/* get the first token */
token = strtok(str, s);
/* walk through other tokens */
while( token != NULL ) {
test[test_count] = token;
test_count++;
token = strtok(NULL, s);
}
strtok() works on your original input string, by replacing the first occurence of a character in the list of delimeters with a '\0'. So yes, this is the intended usage as you describe it.
Side notes:
don't write things like
const char s[2] = "-";
just using
const char s[] = "-";
lets the compiler determine the correct size automatically
in this special case, just passing "-" to strtok() (or a #define to "-") would do fine, a decent compiler recognizes identical string literals and creates only one instance of them.
just in case it's helpful to see some code, here's a simple strtok implementation I did myself a while back.
I am starting to studying C and I already run into few problems.
I want to parse a file and store the results of each line in a structure.
My structure looks like:
struct record {
char x[100];
}
Then, whenever I use strtok to parse a line in some file.txt,
struct record R;
...
char *token;
token = strtok(line, "\t");
token returns a pointer to the string and whenever I print it, it is correct string. I want to assign token to x, such as R.x = token, but I get an error, "char x[100] is not assignable". Is it possible to convert this pointer token to actual char array or what would be the best way to store the results into the structure?
The error says it all. Arrays are not assignable. You need to copy each character one by one and then append a NUL-terminator at the end.
Fortunately there is a function that does this for you. The name of the function is strcpy and it is found in the string.h header.
To fix your issue, use
strcpy(R.x,token);
instead of
R.x = token;
Use strcpy after making sure that the string fits in the array:
#define LEN(array) (sizeof (array) / sizeof (array)[0])
if (strlen(token) < LEN(R.x)) {
strcpy(R.x, token);
} else {
fprintf(stderr, "error: input string \"%s\" is longer than maximum %d\n", token, LEN(R.x) - 1);
}
strcpy stops when it encounters a NULL, memcpy does not.
So if you array have 0x00 eg. \0 in middle,you should use memcpy rather than strcpy.
Using GDB, I find I get a segmentation fault when I attempt this operation:
strcat(string,¤tChar);
Given that string is initialized as
char * string = "";
and currentChar is
char currentChar = 'B';
Why does this result in a segmentation fault?
If strcat can't be used for this, how else can I concat a char onto a string?
As responded by others, ¤tChar is a pointer to char or char*, but a string in C is char[] or const char*.
One way to use strcat to concatenate a char to string is creating a minimum string and use it to transform a char into string.
Example:
Making a simple string, with only 1 character and the suffix '\0';
char cToStr[2];
cToStr[1] = '\0';
Applying to your question:
char * string = "";
char currentChar = 'B';
cToStr will assume the string "B":
cToStr[0] = currentChar;
And strcat will work!
strcat ( string, cToStr );
Because ¤tChar is not a string, it doesn't finish with \0 character. You should define B as char *currentChar = 'B';. Also according to http://www.cplusplus.com/reference/clibrary/cstring/strcat string should have enough space to hold the result string (2 bytes in this case), but it is only 1 byte.
Or if you want to use char then you can do something like (depending of your code):
char string[256];
...
char currentChar = 'B';
size_t cur_len = strlen(string);
if(cur_len < 254) {
string[cur_len] = currentChar;
string[cur_len+1] = '\0';
}
else
printf("Not enough space");
I think the simplest method (not efficient) would be sprintf
sprintf(str, "%s%c", str, chr);
strcat() takes two '\0'-terminated strings. When you pass the address of a character, the routine will look at the memory that follows the character, looking for the terminator.
Since you don't know what that memory even refers to, you should expect problems when your code accesses it.
In addition to that, your string argument does not have room to have any characters appended to it. Where is that memory written to? It will attempt to write past the end of the memory associated with this string.
Both of the strings must be null-terminated. A single char isn't null terminated, so it's undefined when strcat will stop concatenating characters to the end. Also, string must contain at least enough space for both the original string and resultant string.
This works:
char string[10] = "";
char* currentChar = "B";
strcat(string, currentChar);
We know that currentChar = 'B'.
This can be done
strcat(string, "B\0");
If we know currentChar will be hardcoded as 'B', this would be a good approach.
It also removes the need for char currentChar = 'B';
The first argument of strcat must have enough space to hold the rest of the string. "" is a constant string and as such GCC does not allocate space.
Make it an array with enough space:
char buf[1024];
strcat(buf, "");
strcat(buf, "B");
Can u Give solution for this code of typecasting, LPCTSTR(here lpsubkey) to Char*
for below code snippet ,
char* s="HKEY_CURRENT_USER\\";
strcat(s,(char*)lpSubKey);
printf("%S",s);
here it makes error of access violation ,so what will be the solution for that?.
...thanks in advance
There are several issues with your code that might well lead to the access violation. I don't think any have anything to do with the cast you mentioned.
You are assigning a pointer to the first element of a fixed size char array to a char * and then attempt to append to this using strcat. This is wrong as there is no additional space left in the implicitly allocated string array. You will need to allocate a buffer big enough to hold the resulting string and then copy the string constant in there before calling strcat. For example, like so:
char *s = (char*)malloc(1024 * sizeof(char));
strcpy(s, "HKEY_CURRENT_USER\\");
strcat(s, T2A(lpSubKey));
printf("%s", s);
free(s);
Please note that the fixed size array I'm allocating above is bad practise. In production code you should always determine the correct size of the array on the go to prevent buffer overflows or use functions like strncat and strncpy to ensure that you are not copying more data into the buffer than the buffer can hold.
These are not the same thing. What are you trying to do?
The problem is you are trying to append to a string that you have not reserved memory for.
Try:
char s[1024] = "HKEY_CURRENT_USER";
strcat(s,(char*)lpSubKey );
printf("%S",s);
Do be careful with the arbitrary size of 1024. If you expect your keys to be much longer your program will crash.
Also, look at strcat_s.
ATL and MFC has set of macros to such conversion, where used next letters:
W - wide unicode string
T - generic character string
A - ANSI character string
OLE - BSTR string,
so in your case you need T2A macros
strcat does not attempt to make room for the combination. You are overwriting memory that isn't part of the string. Off the top of my head:
char *strcat_with_alloc(char *s1, char *s2)
{
if (!s1 || !s2) return NULL;
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
char *dest = (char *)malloc(len1 + len2 + 1);
if (!dest) return NULL;
strcpy(dest, s1);
strcat(dest, s2);
return dest;
}
now try:
char* s="HKEY_CURRENT_USER\\";
char *fullKey = strcat_with_alloc(s,(char*)lpSubKey);
if (!fullKey)
printf("error no memory");
else {
printf("%S",fullKey);
free(fullKey);
}