i would like to copy data of char* to another last address of char*
illustration
var1 -> O
var2 -> K
first step
var1 -> OK
var2 -> K
copy var2 to var1
result
var1 -> OK
written code
#include <stdio.h>
#include <string.h>
void timpah(char *dest, char *src, int l_dest, int l_src)
{
int i = 0;
while(i < l_dest)
{
dest[l_dest+i] = src[l_src+i];
i++;
}
}
int main()
{
char res[2024];
res[1] = 0x4f;
char a[] = {0x4b};
timpah(res,a,1,1);
printf("%s [%d]\n",res,strlen(res));
return 0;
}
run
root#xxx:/tmp# gcc -o a a.c
root#xxx:/tmp# ./a
[0]
question
why my code is not working ? or is there any function had exists already to perform these, but i haven't know it yet ?
thx for any attention
You aren't setting res[0] at any point. If res[0] contains \0 your string ends there. You are probably making things harder than they have to be; you can always use strncpy and strncat.
You probably should have a look at strncat(), strncpy(), etc
#include <stdio.h>
#include <string.h>
void timpah(char *dest, char *src, int l_dest, int l_src)
{
int i = 0;
while(i < l_dest)
{
dest[l_dest+i] = src[l_src+i];
i++;
}
}
int main()
{
char res[2024];
res[0] = 0x4f;
char a[] = {0x4b};
timpah(res,a,1,0);
res[2] = '\0';
printf("%s [%d]\n",res,strlen(res));
return 0;
}
Related
I am following this algorithm that will copy one string to another string:
[S is a source string and T is a target string]
1. Set I = 0
2. Repeat step 3 while S[I] ≠ Null do
3. T[I] = S[I]
4. I = I + 1
[End of loop]
5. Set T[I] = Null
6. Return
I have attempted it but it instead removes the first n characters from source string relative to length of target string. For example:
#include <stdio.h>
#include <stdlib.h>
char const* stringCopy(char* T, char const* S){
while(*S){
*T++ = *S++;
}
//*T = 0;
return T;
}
int main(void){
char sentence[100] = "some sentence";
char* again = "another";
printf("%s", stringCopy(sentence, again));
return EXIT_SUCCESS;
}
You return the incremented original pointer T. Make a copy of T for the copy loop and return the original pointer.
#include <stdio.h>
#include <stdlib.h>
char const* stringCopy(char* T, char const* S){
char *ptr = T;
while(*ptr++ = *S++);
return T;
}
int main(void){
char sentence[100] = "some sentence";
char* again = "another";
printf("%s", stringCopy(sentence, again));
return EXIT_SUCCESS;
}
I have a structure inside which char array and int value is maintained. I want to treat this char array as a flat array to store the list of strings and the offset will track the starting position where the string is added in the array.
Structure is shown below:
struct A
{
char element[256];
int offset;
}
Also, I want to delete the strings after performing some operation if found.
Please let me know if this feasible. If yes then how?
Yes, append to a.element[a.offset].
To delete, set a.element[0] to the null byte. C strings end at a null byte.
#include <stdio.h>
#include <string.h>
typedef struct
{
char element[256];
int offset;
} A;
void A_append(A* a, const char *str) {
// Concatenate on the end of element.
strcat(&a->element[a->offset], str);
// Increment the offset to the new end.
a->offset += strlen(str);
}
void A_delete(A* a) {
a->element[0] = '\0';
a->offset = 0;
}
int main() {
A a = { .element = "" };
a.offset = 0;
char string1[] = "one";
A_append(&a, string1);
char string2[] = "two";
A_append(&a, string2);
puts(a.element);
A_delete(&a);
puts(a.element);
}
You can also store a pointer to the end of element. It's the same thing, just more direct.
#include <stdio.h>
#include <string.h>
typedef struct
{
char element[256];
char *end;
} A;
void A_append(A* a, const char *str) {
// Concatenate nto the end of element.
strcat(a->end, str);
// Increment the pointer to the new end.
a->end += strlen(str);
}
void A_delete(A* a) {
a->element[0] = '\0';
a->end = a->element;
}
int main() {
A a = { .element = "" };
a.end = a.element;
char string1[] = "one";
A_append(&a, string1);
char string2[] = "two";
A_append(&a, string2);
puts(a.element);
A_delete(&a);
puts(a.element);
}
Finally, if you want to store a list of strings, not concatenate them, consider storing them as pointers.
Since all we have to go on is the question if it's feasible - and the answer is yes. Here's a way showing that it is:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct A A;
struct A {
char element[256];
int offset;
};
A *A_create() {
A *a = malloc(sizeof *a);
a->offset = 0;
return a;
}
void A_destroy(A *a) {
free(a);
}
// return false if the string doesn't fit
// true if it's successfully added
bool A_add_string(A *a, const char *str) {
size_t len = strlen(str);
if(a->offset + len >= sizeof a->element) return false;
memcpy(a->element + a->offset, str, len + 1);
a->offset += len + 1;
return true;
}
You can now create an A, add \0 terminated strings to it and finally destroy it:
A *a = A_create();
A_add_string(a, "Hello");
A_add_string(a, "world");
A_destroy(a);
C- language——-Trying to call a function "test" from main(). This takes 3 arguments argc, argv and a pointer function which either turns the string into lower case or upper case. Then using the array of modified values i will just loop and print them.
I get segmentation fault error.
I want to return the entire array. So that in my main() i will loop through it and print it. How can i do this? Where am i going wrong in my code? Any help would be great.
Your codes have some incorrect points and are redundant as well.
You can try the below codes
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
char **test(int argc, const char *const *argv, int (*const chnge)(int)){
char **retArr = malloc((argc+1) * sizeof(char*));
for (int i = 0; i < argc; ++i) {
const char *str = argv[i];
int len = strlen(str);
char* transform = malloc((len+1) * sizeof(char));
for (int j = 0; j < (len+1); ++j) {
transform[j] = chnge(str[j]);
}
retArr[i] = transform;
}
retArr[argc] = NULL; // An array of char* terminated by NULL
return retArr;
}
int main(int argc, const char *const *argv) {
char **val1 = test(argc, argv, &toupper);
char **val2 = test(argc, argv, &tolower);
for (char *const *p = val1, *const *q = val2; *p && *q; ++argv, ++p, ++q) {
printf("[%s] -> [%s] [%s]\n", *argv, *p, *q);
free(*p);
free(*q);
}
free(val1);
free(val2);
}
I believe the answer may have to do with the fact that you are trying to directly act on a string 1. without using strcpy, and 2. using a pointer array (char*) instead of an array object (char[]) which can cause a segfault.
Sorry, this would better be suited to a comment and not an answer, but I unfortunately can't comment quite yet. This may be of help?
I have created a function for strend, which basically returns 1 if string t is present at the end of string s, however it never returns 1:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int strend(char *s, char *t) {
int p;
for (p = 0; p < strlen(s) - strlen(t); p++) {
*s++;
}
printf("%s\n%s\n", s, t);
if (s == t)
return 1;
return 0;
}
int main(void) {
int bool = strend("Hello", "ello");
printf("%i\n", bool);
return 0;
}
This gives me an output of:
ello
ello
0
So technically I should get 1. I assume the comparison using pointers is not used in this way?
You need to review your basic knowledge of C strings. There are lots of standard string functions in string.h that can help you with this test.
The basic problem is that the test s == t is valid, but you are comparing memory addresses here. You can see that is valid if you change the strings to test to
char test[] = "Hello";
int bool = strend_(test, test+1);
where test obviously is the same as your "Hello", and similarly, test+1 is the same as "ello" (try it by printing them). This correctly returns 1 with your routine.
In addition, I get two warnings:
on *s++; "warning: expression result unused [-Wunused-value]": you increment s but also ask what character is at that position through *s; and you don't use that information.
Fix by removing the * there.
on p < strlen(s) ..; "warning: comparison of integers of different signs: 'int' and 'unsigned long'", because strlen does not return a signed integer but an unsigned one (apparently, my header uses unsigned long).
Fix by declaring p as unsigned long, or even better, size_t.
Your entire routine can be condensed to a simple
int strend (char *s, char *t)
{
if (strlen(s) >= strlen(t) && !strcmp (s+strlen(s)-strlen(t),t))
return 1;
return 0;
}
It's not worth the trouble to cache the result of those four strlen calls into 2 temporary variables; a good compiler will work it out and do that for you. (A quick glance to the assembly output of the compiler I'm using – clang – shows it does, even with the default optimization settings.)
A slightly modified test, based on #M.M.'s comment:
int strend (char *s, char *t)
{
if (strlen(s) < strlen(t)) return 0;
return !strcmp (s+strlen(s)-strlen(t),t);
}
but attempting to optimize it this way is not as easy parsed as the routine above, and its assembly is ever so slightly "wordy" as well. Personally, I'd go for the more humanly readable version.
Use strcmp(3)
if (strcmp(s, t) == 0) return 1;
This actually compares the contents of the memory pointed to by s and t rather than their addresses.
Your code is broken in multiple ways:
The initial loop is a very cumbersome way to advance p by the difference of lengths if positive.
Once you have pointers at the same distance from the end of both strings, You should compare the characters with strcmp() (or memcmp() if you can first exclude the case of strlen(s) < strlen(t).
Comparing the pointers obtained after the loop will only work if t points inside the string pointed to by s, a special case that may or may not be produced by the compiler for the specific call in main: strend("Hello", "ello");.
Here is a modified version:
#include <string.h>
int strend(const char *str1, const char *str2) {
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
return len1 >= len2 && !memcmp(str1 + len1 - len2, str2, len2);
}
I corrected/modified your code, here is the code,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#pragma warning(disable:4996)
int strend(char *s, char *t)
{
int p,flag=0,count=0;//count will be the starting index for *t
p = strlen(s) - strlen(t);//this will be the starting index for *s
while(count<strlen(t))
{
if (*(s+p) == *(t+count))
{
flag = 1;
count++;
p++;
continue;
}
else
{
flag = 0;
break;
}
}
return flag;
}
int main(void)
{
int flag = strend("Hello", "ello");
printf("%i\n", flag);
return 0;
}
This code works too.
#include <stdio.h>
#include <string.h>
int strend (char *s1, char *s2);
void main ()
{
char str1[20] = "somethings";
char str2[20] = "things";
int f;
f = strend (str1,str2);
if (f==1)
printf ("1");
else
printf ("0");
}
int strend (char *str1, char *str2)
{
int l = strlen(str1) - strlen(str2);
str1 = str1 + l;
int d = strcmp(str1,str2);
if (d == 0)
return 1;
else
return 0;
}
this code works well.
int strend(char *s, char *t){
while(*t & *s){
if(*t == *s){
t++;
}
s++;
}
return *t==*s;
}
It's a beginners question: Why is this breaking/giving an error?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *strtrim_right(char *p)
{
char *end;
int len;
len = strlen( p);
while (*p && len)
{
end = p + len-1;
if(isalpha(*end))
*end =0;
else
break;
}
return(p);
}
int main ()
{
char *x="PM123BFD";
strtrim_right(x);
printf("%s", x);
return 0;
}
Change
char *x="PM123BFD";
to
char x[]="PM123BFD";
You cannot modify a string literal, so instead pass the function a char array which it can modify.
I don’t see why it should break – I would rather expect an infinite loop: the while condition will always be true and the loop will never be left.
Rework the loop condition, it’s borked. Then look at the variables you have: you never change the values of either p or len. This isn’t right. Furthermore, the code inside the loop is much more complicated than need be. Think about whether you really need three variables here.
Ok thanks to the 2 answers above here is what seems to be ok now:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *strtrim_right(char *p)
{
char *end;
int len;
len = strlen( p);
while (*p && len)
{
end = p + len-1;
if(isalpha(*end))
*end =0;
else
break;
len = strlen(p);
}
return(p);
}
int main ()
{
char x[]="PM123BFD";
strtrim_right(x);
printf("%s", x);
return 0;
}