my problem is in convert a char to string
i have to pass to strcat() a char to append to a string, how can i do?
thanks!
#include <stdio.h>
#include <string.h>
char *asd(char* in, char *out){
while(*in){
strcat(out, *in); // <-- err arg 2 makes pointer from integer without a cast
*in++;
}
return out;
}
int main(){
char st[] = "text";
char ok[200];
asd(st, ok);
printf("%s", ok);
return 0;
}
Since ok is pointing to an uninitialized array of characters, it'll all be garbage values, so where the concatenation (by strcat) will start is unknown. Also strcat takes a C-string (i.e. an array of characters which is terminated by a '\0' character). Giving char a[200] = "" will give you a[0] = '\0', then a[1] to a[199] set to 0.
Edit: (added the corrected version of the code)
#include <stdio.h>
#include <string.h>
char *asd(char* in, char *out)
{
/*
It is incorrect to pass `*in` since it'll give only the character pointed to
by `in`; passing `in` will give the starting address of the array to strcat
*/
strcat(out, in);
return out;
}
int main(){
char st[] = "text";
char ok[200] = "somevalue"; /* 's', 'o', 'm', 'e', 'v', 'a', 'l', 'u', 'e', '\0' */
asd(st, ok);
printf("%s", ok);
return 0;
}
strcat will not append single characters. Instead it takes a const char* (a full C-style string) which is appended to the string in the first parameter. So your function should read something like:
char *asd(char* in, char *out)
{
char *end = out + strlen(out);
do
{
*end++ = *in;
} while(*in++);
return out;
}
The do-while loop will include the zero-terminator which is necessary at the end of C-style strings. Make sure that your out string is initialized with a zero-terminator at the end or this example will fail.
And as an aside: Think about what *in++; does. It will increment in and dereference it, which is the very same as in++, so the * is useless.
To look at your code, I can make a couple of pointers in relation to it, this is not a criticism, take this with a pinch of salt that will enable you to be a better C programmer:
No function prototype.
Incorrect usage of pointers
Dealing with the strcat function is used incorrectly.
Overdoing it - no need for the asd function itself!
Usage of dealing with variables notably char array that is not properly initialized.
#include <stdio.h>
#include <string.h>
int main(){
char st[] = "text";
char ok[200];
ok[0] = '\0'; /* OR
memset(ok, 0, sizeof(ok));
*/
strcat(ok, st);
printf("%s", ok);
return 0;
}
Hope this helps,
Best regards,
Tom.
To convert a character to a (null terminated) string you could simply do:
char* ctos(char c)
{
char s[2];
sprintf(s, "%c\0", c);
return s;
}
Working example: http://ideone.com/Cfav3e
Related
#include <stdio.h>
#include <stdlib.h>
char wordsum(char FW[256],char SW[256]){
int i;
int j=strlen(FW);
for (i=0;i<=strlen(SW);i++)
FW[i+j+1]=SW[i];
printf("%c",FW);
return FW;
}
int main()
{
char F[256];
char S[256];
printf("Enter the first word\n");
gets(F);
printf("Enter the Second word\n");
gets(S);
wordsum(F,S);
return 0;
}
I don't know what is wrong with my code to make strcat function. I hope to find the answer.
I assume that the code is written to learn more about the C language. If so, may I present an alternative implementation which does not use strlen(). The intention is to present some of the really nice features in the language. It may be a bit complicated to wrap ones head around the first time, but IIRC the code can be found in K&R's book The C Programming Language.
Here we go:
char* mystrcat(char *dest, const char *src)
{
char *ret = dest;
while (*dest)
dest++;
while ((*dest++ = *src++))
;
return ret;
}
The first while-loop finds the end of the destination string. The second while-loop appends the source string to the destination string. Finally, we return a pointer to the original dest buffer.
The function could've been even nicer if it didn't return a pointer.
void mystrcat(char *dest, const char *src)
{
while (*dest)
dest++;
while ((*dest++ = *src++))
;
}
HTH
There are several mistakes in your code. They are:
1) A function can't return an array in C and you don't need to do so. Change the return type from char to void of wordsum and erase the line return FW;
2) You want to print a string, right? Format specifier for string is %s. So write printf("%s",FW); instead of printf("%c",FW);.
3) Do this: FW[i+j]=SW[i];. Why did you add an extra 1 to i+j? Just think logically.
4) Add header file for strlen(), it's <string.h>.
5) Erase those asterisk marks before and after FW[i+j]=SW[i];.
There are a few problems in your function, I've changed and commented them below:
char *wordsum(char FW[256],char SW[256]){ // correct function type
int i;
int j=strlen(FW);
for (i = 0; i <= strlen(SW); i++)
FW[i+j] = SW[i]; //change 'i + j + 1' to 'i + j'
printf("%s",FW); //change format specifier as you are printing string not character
return FW;
}
Then dot forget to capture the returned pointer using a char* variable in the calling function (here main())
char *result;
result = wordsum(F,S);
printf("\n%s\n", result);
Working example: https://ideone.com/ERlFPE
I am trying to figure out the proper syntax to returned two scanned strings so that I can use them in main using pointers.
void get_user_info(char* user_string_one[20] , char* user_string_two[20]) {
char string_one[20] = "";
char string_two[20] = "";
string_one = "hello";
string_two = "goodbye";
*user_string_one = string_one;
*user_string_two = string_two;
return;
}
int main(void) {
char user_string_one[20] = "";
char user_string_two[20] = "";
get_user_info(user_string_one[20], user_string_two[20]);
printf("%s %s\n", user_string_one, user_string_two);
return 0;
}
I am sure I am making a really simple mistake, I just can't seem to figure it out.
#include <stdio.h>
#include <string.h>
void get_user_info(char* user_string_one, char* user_string_two)
{
strcpy(user_string_one, "hello");
strcpy(user_string_two, "goodbye");
}
int main(void)
{
char user_string_one[20];
char user_string_two[20];
get_user_info(user_string_one, user_string_two);
printf("%s %s\n", user_string_one, user_string_two);
return 0;
}
Strings can't be passed around that way in C. When an array is passed to a function as an argument, the function receives a pointer to the first element only. A pointer is not an array.
You need to use functions in the standard header <string.h> to copy data in strings. For example;
#include <string.h>
void get_user_info(char* user_string_one , char* user_string_two)
{
strcpy(user_string_one, "hello");
strcpy(user_string_two, "goodbye");
}
int main(void)
{
char user_string_one[20] = "";
char user_string_two[20] = "";
get_user_info(user_string_one, user_string_two);
printf("%s %s\n", user_string_one, user_string_two);
return 0;
}
Bear in mind that a string literal, like "hello", is represented as an array of char, with a terminating '\0' (a char with value zero) appended (a marker representing the end). So "hello" is represented in memory using the six characters 'h', 'e', 'l', 'l', 'o', and '\0'. strcpy() and similar functions ASSUME strings are provided in that form and relies on destination arrays (the ones being copied to) being long enough to hold everything up to and including the '\0' marker.
so I was practicing writing c code with pointers using the K&R. For one problem with strcat function, I couldn't find out what was wrong with my code, which according to Visual Studio, returned the destination string unchanged after the strcat function. Any suggestion is appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int strcat(char* s, char* t);
int main(void)
{
char *s="hello ", *t="world";
strcat(s,t);
printf("%s",s);
return 0;
}
int strcat(char* s,char* t)
{
int i;
i=strlen(s)+strlen(t);
s=(char*) malloc(i);
while(*s!='\0')
s++;
while('\0'!=(*s++=*t++))
;
return 0;
}
I'm pretty sure that strcat returns a char* in the real implementation (holding the original value of the first string).
strcat is not supposed to alter the first parameter's address, so you shouldn't call malloc.
Point #2 means that you need to declare char *s as char s[20] in main (where 20 is some arbitrary number big enough to hold the whole string).
If you really want to alter the value of the an input parameter you will need to pass the address of the value - so it would need to be strcat(char **s, ...) in the function declaration/definition, and called with strcat(&s, ...) in main.
1) defining string in this way
char *s="hello "
means that you are defined a literal string. a literal string is saved into read only memory so you can not edit it
you have to define your string as a char array in order to be able to edit it
char s[100] = "hello ";
2) when you define your function in this way
int strcat(char* s,char* t)
you can not change the address of s into the function strcat(). So assigning memory with malloc() into the function will not change the s address when leaving the function
3) change your function strcat to
int strcat(char** s,char* t)
{
int i;
char *u, *v;
i=strlen(*s)+strlen(t);
v = *s;
u=(char*) malloc(i+1);
while(*v!='\0')
*u++ = *v++;
while('\0'!=(*u++=*t++));
*s = u;
return 0;
}
and you call it in the main with:
char *s="hello ", *t="world";
strcat(&s,t);
In
strcat(char* s, char* t)
the 's' is send by value. The value of 's' at call time is copied into the stack then strcat() is call. At the return of strcat the modified version is discard from the stack. So the calling value of 's' is never changed (and you create a memory leak).
Beward, in C every memory cell can be change, even parameters or instructions sections; some changes can be very hard to understand.
Since you are trying to do like the real strcat it's said that the first parameter
The string s1 must have sufficient space to hold the result.
so you don't need to use malloc
char *strcat(char* s, const char* t);
int main(void)
{
char s[15] = {0}; //
char *t = "world"; //const char * so you can't change it
strcpy(s, "Hello ");
strcat(s,t);
printf("%s\n",s);
return (0);
}
char *strcat(char* s, const char* t)
{
int i = 0;
while (s[i] != '\0')
i++;
while (*t != '\0')
s[i++] = *t++;
s[i] = '\0'; //useless because already initialized with 0
return (s);
}
#include<stdio.h>
#include<string.h>
#define LIMIT 100
void strcatt(char*,char*);
main()
{
int i=0;
char s[LIMIT];
char t[LIMIT];
strcpy(s,"hello");
strcpy(t,"world");
strcatt(s,t);
printf("%s",s);
getch();
}
void strcatt(char *s,char *t)
{
while(*s!='\0')
{
s++;
}
*s=' ';
++s;
while(*t!='\0')
{
*s=*t;
s++;
t++;
}
*s=*t;
}
Dear user,
you don't have to complicate things that much. The simpliest code for strcat, using pointers:
void strcat(char *s, char *t) {
while(*s++); /*This will point after the '\0' */
--s; /*So we decrement the pointer to point to '\0' */
while(*s++ = *t++); /*This will copy the '\0' from *t also */
}
Although, this won't give you report about the concatenation's success.
Look at this main() part for the rest of the answer:
int main() {
char s[60] = "Hello ";
char *t = "world!";
strcat(s, t);
printf("%s\n", s);
return 0;
}
The s[60] part is very important, because you can't concatenate an another string to it's end if it doesn't have enough space for that.
I see a very interesting code to reverse a string,
but I don't understand here:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void Reverse(char *s);
int main()
{
char *s=NULL;
s=(char *)malloc(sizeof(char *));
gets(s);
Reverse(s);
puts(s);
return 0;
}
void Reverse(char *s)
{
char *end=s;
char tmp;
if (s)
{
while (*end)
{
++end;
}
--end;
while (s<end) ??
{
tmp=*s;
*s++=*end;
*end--=tmp;
}
}
}
I see the this program tries to work on the same string by using end=s to change both string at the same time, but what does '*' line : while(s<end) here mean?
I use gdb and find that when we input asdfgh, when *s is fdsa and *end is fds, this is no longer true, how this line controls the program?
I just want to know what '??' line mean..
Thanks a lot !
Strings in C are terminated by the \0 character, which has the integer value 0. As such it is a false value.
By using while(*end) you check whether end is pointing on the termination character of the given string. If it isn't pointing on the end, you move it further (++end). To ensure that the pointer is valid you move the "cursor" backward after this.
while(s < end) will now move check whether s is further forwarded than end. If not, then you'll swap the value of both "cursor". end will move toward s and vice versa. This way you're going to reverse the string.
You're debugging output is a result of gdbs interpretation. It interpreds end as a string, not a single character. Have a look at *end while debugging.
Note that your malloc is completely wrong. You have to allocate enough memory for the string, for example s = malloc(500*sizeof(char));. Use fgets instead, where you can specify the maximum number of characters to be read. Don't forget to free all memory you allocate:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 500
void Reverse(char *s);
int main()
{
char* s = malloc(BUFFER_SIZE * sizeof(char));
fgets(s,BUFFER_SIZE,stdin);
Reverse(s);
puts(s);
free(s);
return 0;
}
void Reverse(char *s)
{
char* end=s;
char tmp;
if(s)
{
while (*end)
{
++end;
}
--end;
while (s<end)
{
tmp=*s;
*s++=*end;
*end--=tmp;
}
}
}
s and end are char pointer so the test (s < end) is true until the s pointer doesn't become greater than then end pointer.
Example
Assume that you want to reverse the string "hello" stored at the address 0x0000, ad the start of the function you have:
s = 0x0000
end = 0x003
now the while loop:
s=0x0000 e=0x0003 *s=o *e=h
s=0x0001 e=0x0002 *s=l *e=e
s=0x0002 e=0x0003 << while exit >>
I am trying to separate an IPV6 address from a port in C. The address and port will always be given by "'[' + address + ']:' + port", for example: "[2009:7a4d:80d2:33af:0000:0000]:6667". In python, to do this, I would do something similar to the following:
>>> thing = "[2009:7a4d:80d2:33af:0000:0000]:6667"
>>> print thing[-4:]
6667
>>> print thing[1:30]
2009:7a4d:80d2:33af:0000:0000
How do I do the equivalent of python's right-to-left parsing, i.e. [-4:], in C? And, preferably without using regex, how can I say in C that I would like everything between '[' and ']'?
Thanks for any help and advice!
C does not have string manipulation built into the language, so you need to use a few functions. strrchr() searches for a given character from the end of the string. Here's an example of how to use it:
int main()
{
char* thing = "[2009:7a4d:80d2:33af:0000:0000]:6667";
char* a=strrchr(thing,']'); /* Find the last ']' */
char address[128]; /* Make somewhere new to hold the address part */
strncpy(address, thing+1, a-thing-1); /* copy (a-thing)-1 characters, starting from the second character of thing, into address */
printf("port: %s\n",a+2); /* a+2 is two characters from the start of a (where we found the ']') */
printf("address: %s\n",address);
}
You can also write a '\0' into the string as in SashaN's answer, which effectively divides the original string in two. This won't work here as I used a string constant which can't be modified. Note that 'address' must be long enough to hold the address under all cases.
'a' and 'thing' are both pointers, so (a-thing) is used to give the difference (in characters) between the start of thing and the ']'.
char* thing = "[2009:7a4d:80d2:33af:0000:0000]:6667";
char ipv6[30];
strncpy (ipv6, thing + 1, 29);
ipv6[29] = '\0';
It's crude, and only works with the fixed-string constraints you outlined.
You can use strtok_r for this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *saveptr;
char *address;
char *port;
address = strtok_r(argv[1], "[]", &saveptr);
port = strtok_r(NULL, ":", &saveptr);
puts(port);
return EXIT_SUCCESS;
}
Note that I haven't actually parsed it backwards, but that doesn't seem necessary from the information you provided.
Here is a function that will return the substring between the firstmost and lastmost characters in a string, provided as parameter. The exclusive flag tells it whether or not to include those characters in the result.
I'm guessing some additional validation should be done before attempting strncpy(), so be careful.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *substr_betweenchars(char *string, char begin, char end, int exclusive)
{
char *left = strchr(string, begin);
char *right = strrchr(string, end);
char *result = 0;
int a = left - string;
int b = right - string;
int n = b - a + 1 - (!!exclusive << 1);
if (left && right)
{
result = malloc(n * sizeof(char));
strncpy(result, left + !!exclusive, n);
}
return result;
}
int main(void)
{
char string[] = "[2009:7a4d:80d2:33af:0000:0000]:6667";
printf("%s\n", substr_betweenchars(string, '[', ']', 1));
printf("%s\n", substr_betweenchars(string, '[', ']', 0));
printf("%s\n", substr_betweenchars(string, '8', '2', 1));
printf("%s\n", substr_betweenchars(string, '8', '2', 0));
return 0;
}
Output:
$ gcc -Wall -o substr substr.c
$ ./substr
2009:7a4d:80d2:33af:0000:0000
[2009:7a4d:80d2:33af:0000:0000]
0d
80d2
Would you consider using sscanf() here like a regex? It has a regex-like feature that could read the address from the formatted string quite nicely:
char str[] = "[2009:7a4d:80d2:33af:0000:00000]:6667";
char addr[30];
sscanf(str, "[%29[^]]]", addr);
addr[29] = '\0';
printf("%s", addr); /* 2009:7a4d:80d2:33af:0000:0000 */
Otherwise you could just scan through the string looking for the open and close brackets and copy the contents in between as some of the other answers have shown.
man string(3C)
portstr = strrchr(ipv6str, ':');
if (portstr != NULL) {
*portstr = '\0';
portstr++;
}