I have two arrays:
char roundNames1[16][25], roundNames2[16 / 2][25];
I then want to copy a result from the first array to the second. I have tried this:
where roundNames1[5] = "hello"
#include <string.h>
printf("First array: %s", roundNames1[5]);
strcpy(roundNames1[5], roundNames2[6]);
printf("Second array: %s", roundNames2[6]);
But this just returns
First array: hello
Second array:
Why is it not working?
You need to exchange arguments of function strcpy
strcpy( roundNames2[8], roundNames1[5] );
Here is a part pf the function description from the C Standard
7.23.2.3 The strcpy function
Synopsis
1
#include <string.h>
char *strcpy(char * restrict s1, const char * restrict s2);
Description
2 The strcpy function copies the string pointed to by s2 (including
the terminating null character) into the array pointed to by s1. If
copying takes place between objects that overlap, the behavior is
undefined.
strcpy - arguments other way around.
http://www.cplusplus.com/reference/cstring/strcpy/
Copy arrays/strings with memcpy
void * memcpy (void * destination, void * source, size_t size)
The memcpy function copies an certain amount of bytes from a source memory location and writes them to a destinaction location. (Documentation)
Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char some_array[] = "stackoverflow";
int memory_amount = sizeof(some_array);
char *pointer = malloc(memory_amount);
memcpy(pointer, &some_array, memory_amount);
printf("%s\n", pointer);
free(pointer);
return 0;
}
Output
$ ./a.out
stackoverflow
Related
I have tried so many ways of doing this and I cannot get it to work. My setup says to use char[] but everything I've researched has no information on using that. Here is my code below
#include <stdio.h>
#include <string.h>
char[] makeString(char character,int count)
{
char finalString[count];
strcpy(finalString,character);
for(int i=1;i<=count;i++)
{
strcat(finalString,character);
}
return finalString;
}
int main() {
printf("%s\n",makeString("*",5)); }
I'm trying to create a function that returns a string of the given character count amount of times. Any help is greatly appreciated.
My apologies if this is a very simple error, I mostly code in python so C is very new to me.
There are a couple of issues, mainly on char finalString[count];
finalString is a variable created within the function, it is called a local variable. It would be destroyed after the function returns.
count as the value of the count variable is dynamically changed. Its value could not be determined during the compile stage, thus the compiler could not allocate memory space for this array. The compiling would fail.
To fix this issue.
either create this variable outside and pass it into the function. Or create the variable on the HEAP space. As the Heap space are shared across the entire program and it would not be affected by function ending.
either using a constant number or dynamically allocating a chunk of memory with malloc, calloc and etc.
Here is one demo with the full code:
// main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* makeString(char character,int count) {
char* finalString = malloc(count+1); //dynamic allocate a chunk of space. +1 for mimic string end with an extra termination sign 0.
for(int i=0; i<count; i++) {
finalString[i] = character;
}
finalString[count] = 0; // string end signal 0
return finalString; // the memory finalString pointed to is in the HEAP space.
}
int main() {
char * p = makeString('*',5);
printf("%s\n",p);
free(p); // free up the HEAP space
return 0;
}
To compile and run the code.
gcc -Wall main.c
./a.out
The output
*****
Arrays are not a first-class type in C -- there are a lot of things you can do with other types that you can't do with arrays. In particular you cannot pass an array as a parameter to a function or return one as the return value.
Because of this restriction, if you ever declare a function with an array type for a parameter or return type, the compiler will (silently) change it into a pointer, and you'll actually be passing or returning a pointer. That is what is happening here -- the return type gets changed to char *, and you return a pointer to your local array that is going out of scope, so the pointer you end up with is dangling.
Your code doesn't compile. If you want to return an array you do char * not char []. Local variables like finalString are out of scope after the function returns.
Here are 3 ways of doing it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *initString(char *a, char c, int n) {
memset(a, c, n);
a[n] = '\0';
return a;
}
char *makeString(char c, int n) {
char *a = malloc(n + 1);
memset(a, c, n);
a[n] = '\0';
return a;
}
int main(void) {
printf("%s\n", memset((char [6]) { 0 }, '*', 5));
char s[6];
initString(s, '*', (sizeof s / sizeof *s) - 1);
printf("%s\n", s);
char *s2 = makeString('*', 5);
printf("%s\n", s2);
free(s2);
}
This question already has answers here:
Different answers from strlen and sizeof for Pointer & Array based init of String [duplicate]
(4 answers)
Closed 3 years ago.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main()
{
unsigned char str[] = "abcdefg";
unsigned char *str1 = (unsigned char*)malloc(sizeof(str) -1);
memcpy(str1, str, (sizeof(str)-1) );
for(int i = 0; i<(sizeof(str1)); i++)
printf("%c", str1[i]);
free(str1);
}
I want copy the string str to str1 but the output is
abcd
It means that only pointer byte(4byte) is copied.
And i try
printf("%d", sizeof(str)-1 );
it's output is 7
What is my mistake?
it mean that only pointer byte(4byte) is copied.
No, it does not. You're assuming that your printout is correct, which it is not. You can use sizeof on arrays but not on pointers. Well, you can, but it means something different.
Everything is copied. You're just printing the first four characters. Change to:
for(int i = 0; i<(sizeof(str) - 1); i++)
Also, don't cast malloc. Here is why: Do I cast the result of malloc?
First the mistakes and then the correct code:
Mistakes:
Don't ever use sizeof(str) to get the length of the string. It doesn't work with pointers. Instead, use strlen(str) + 1.
You are subtracting 1 from the size of the string on malloc call. Why? You are not making space for the ending NULL character.
When copying strings, if you know that the destination string is large enough to store the source, use strcpy instead of memcpy. If you only want an additional size parameter like in memcpy, use strncpy. memcpy is not meant to deal with strings, but with plain arrays.
The correct type to use for strings is char, not unsigned char.
Not really a mistake, but to print a string you can use printf("%s", str) or puts(str). Why bother with a for loop?
void main() is prohibited by the C standard.
Correct code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str[] = "abcdefg";
char str1* = malloc(strlen(str) + 1);
strcpy(str1, str);
puts(str1);
free(str1);
//return 0; - default in C99 and later
}
str1 is a pointer whereas str is a character array. When you say sizeof(str1) in your for loop, it iterates 4 times because sizeof(str1) must have evaluated to 4(a 32 bit compiler) whereas sizeof(str) evaluates to the correct length.
You should read What is the size of a pointer? once to know more about size of pointers.
Fixed code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main()
{
unsigned char str[] = "abcdefg";
unsigned char *str1 = (unsigned char*)malloc(sizeof(str) -1);
memcpy(str1, str, (sizeof(str)-1) );
for(int i = 0; i<(sizeof(str) - 1); i++)
printf("%c", str1[i]);
free(str1);
}
The following program works fine, and I'm surprised why :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void xyz(char **value)
{
// *value = strdup("abc");
*value = "abc"; // <-- ??????????
}
int main(void)
{
char *s1;
xyz(&s1);
printf("s1 : %s \n", s1);
}
Output :
s1 : abc
My understanding was that I have to use strdup() function to allocate memory for a string in C for which I have not allocated memory. But in this case the program seems to be working fine by just assigning string value using " ", can anyone please explain ?
String literals don't exist in the ether. They reside in your programs memory and have an address.
Consequently you can assign that address to pointers. The behavior of your program is well defined, and nothing bad will happen, so long as you don't attempt to modify a literal through a pointer.
For that reason, it's best to make the compiler work for you by being const correct. Prefer to mark the pointee type as const whenever possible, and your compiler will object to modification attempts.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void xyz(char const **value)
{
*value = "abc";
}
int main(void)
{
char const *s1;
xyz(&s1);
printf("s1 : %s \n", s1);
s1[0] = 'a'; << Error on this line
}
Your program works fine because string literal "abc" are character arrays , and what actually happens while assigning a string literal to a pointer is , the compiler first creates a character array and then return the address of the first element of the array just like when we call the name of any other array.
so in your program you have passed address of a char pointer to the function xyz
and
*value = "abc";
for this statement , compiler first creates a character array in the memory and then returns its address which in turn gets stored in the char pointer.It is worth knowing that the compiler creates the char array in read only memory.Thus , the address returned refers to a const char array.Any attempt to modify its value will return it compile-time error.
You can define a string in C with char *str = "some string";, str is a pointer which points to the location of the first letter in a string.
I am trying to convert string from 'ascii' to 'utf-8', the 'lencoded_str' function will take a pointer char and return another pointer char. the input pointer char size is unknown, and it will change each time the 'lencoded_str' function called. my problem is the 'lencoded_str' function always return nothing.
Any help would be much appreciated.
this is just an example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>
char *lencoded_str(char *in_str){
iconv_t iconv_obj = iconv_open("utf-8","ascii");
char *out_str = calloc(strlen(in_str) * 2, sizeof(char));
char *out_str_start = out_str;
size_t in_str_bytes_left = strlen(in_str);
size_t out_str_bytes_left = strlen(in_str) * 2;
int iconv_return = iconv(iconv_obj, &in_str, &in_str_bytes_left, &out_str, &out_str_bytes_left);
iconv_close(iconv_obj);
return out_str;
}
int main( ){
printf("out: %s\n", lencoded_str("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"));
printf("out: %s\n", lencoded_str("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"));
printf("out: %s\n", lencoded_str("123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"));
}
iconv advances toe input and output string pointers so that they point at the end of the converted string.
That means you must save the original value of the char buffer and return it. You've already had the right idea with out_str_start, but you don't use it:
return out_str_start;
By using the return value from lencoded_str directly in printf and not storing it, you will leak the memory that yopu calloced. You could also go easy on the strlens; you only need to call it once.
This code compiles fine but give segmentation fault error while running? Can anyone tell why?
#include <stdio.h>
#include <string.h>
#include <math.h>
int main() {
const char s2[] = "asdfasdf";
char* s1;
strcpy(s1, s2);
printf("%s", s1);
return 0;
}
You allocated space for a single pointer, s1, but not the bytes pointed at by s1.
A solution is to dynamically allocate memory for s1:
s1 = (char *)malloc(strlen(s2) + 1);
strcpy(s1, s2);
Keep in mind that you need to allocate one more byte of memory (the +1 in the call to malloc) than the number of characters in s2 because there is an implicit NULL byte at the end.
See C Memory Management (Stack Overflow) for more information.
You didn't allocate memory for s1. You have a pointer to s1 but no memory allocated for the strcpy to copy the value of s2 into.
char *s1 = malloc( strlen(s2) + 1 );
strcpy( s1, s2 );
You have not allocated any memory to s1. It is a pointer to nothing.
char* s1 = malloc(sizeof(s2));
strcpy(s1, s2);
printf("%s", s1);
free(s1);
The problem is that s1 does not have any memory associated with it. strcpy does not call malloc().
You could either do:
char s1[10];
or
char *s1 = malloc(10);
What they all said, you need to allocate the space for s1. What everyone else has posted will work just fine, however, if you want a simpler way to allocate space for an existing string and copy it into a new pointer then use strdup like this:
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
int main() {
const char s2[] = "asdfasdf";
char* s1;
s1 = strdup(s2);
printf("%s", s1);
return 0;
}
Someone mentioned strdup earlier, that would be a way to use it. Most systems should support it since it is in the standard C libaries. But apparently some don't. So if it returns an error either write your own using the method already mentioned, or just use the method already mentioned ;)
No one yet has pointed out the potential of strdup (String Duplicate) to address this problem.
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std;
int main() {
const char s2[] = "asdfasdf";
char* s1;
s1 = strdup(s2); // Allocates memory, must be freed later.
printf("%s", s1);
free(s1); // Allocated in strdup, 2 lines above
return 0;
}
You need to allocate the destination (and using namespace std; isn't C but C++, the rest of the code is C).
You have to allocate memory to the pointer s1. If you don't do that, it will be pointing somewhere unknown, and thus arriving at the segmentation fault. The correct code should be:
#include <stdio.h>
#include <string.h>
#include <math.h>
int main() {
const char s2[] = "asdfasdf";
char* s1 = malloc(21 * sizeof(s2[0]));
strcpy(s1,s2);
printf("%s",s1);
return 0;
}