merging of text - c

Can you please help me with merging of two texts into one using just only stdio.h and stdlib.h? The result should be HelloWorld.
So far, I have the following, but there is a mistake somewhere.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
char *spojeni(char *t1, char *t2)
{
char pole_spolecne[10];
for (*t1 = 0; *t1 < 5; t1++)
{
pole_spolecne[*t1] = *t1;
}
for (*t2 = 0; *t2 < 10; t2++)
{
pole_spolecne[*t2 + 5] = *t2;
}
return pole_spolecne;
}
int main()
{
char pole1[] = { "Hello" };
char pole2[] = { "World" };
printf("%s\n", spojeni(pole1, pole2));
system("pause");
return 0;
}
My new solution, but it returns an error at the end:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
char *spojeni(char *t1, char *t2)
{
char pole_cele[20];
char *p_pole_cele;
p_pole_cele = t1;
strcat(p_pole_cele, t2);
return p_pole_cele;
}
int main()
{
char pole1[] = { "Hello" };
char pole2[] = { "World" };
char *p_pole1;
char *p_pole2;
p_pole1 = pole1;
p_pole2 = pole2;
printf("%s\n)", spojeni(p_pole1, p_pole2));
system("pause");
return 0;
}
Finally, this change of function helped:
char *spojeni(char *t1, char *t2)
{
char pole_cele[20];
char *p_pole_cele;
p_pole_cele = (char *)malloc(10);
strcpy(p_pole_cele, t1);
p_pole_cele = (char *)realloc(p_pole_cele, 20);
strcat(p_pole_cele, t2);
return p_pole_cele;
}

I am not quite sure how to answer this, as this is clearly a teaching exercise, and, to be blunt, the code given shows a lack of understanding of pointers. And pointers is a topic better taught in person than via a web-site comment.
A few hints, though:
Think very clearly about pointers, what they are pointing to, and what makes them different from array indices.
Draw diagrams to visualize what you're doing.
Your exercise can be solved using calloc(), strlen() and strcpy().

Related

search of string in an array of strings

i wrote some code that is supposed to find the location of a given string in an array of strings.
problem is- it doesn't give the location. it gives something else.
i understand that probably the problem has to do with the differences between the pointers that are involved- a previous version that dealt with finding the position of a letter in a word worked well.
after a lot of attempts to figure out where is the bug, i ask your help.
kindly, explain me what should be done.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int what (char * token);
main()
{
int i=0;
char string[]="jsr";
char *token;
token=&string[0];
i=what(token);
printf(" location of input is %d \n", i);
return 0;
}
int what (char * token)
{
int i=1;
char *typtbl[]={"mov",
"cmp",
"add",
"sub",
"not",
"clr",
"lea",
};
char * ptr;
ptr=(char *)typtbl;
while (!(strcmp(ptr,token)==0))
{
ptr=(char *)(typtbl+i);
i++;
}
return i;
}
As pointed out, you did not design function what properly. What value should it return if your search function go through all the pointers but does not find the desired string? Typically in that case return -1 would be a choice to indicate nothing found. Also in this case, using a for loop would probably be more suitable, you can just return the index immediately instead of going through all pointers.
int what(char *token)
{
char *typtbl[] = {
"mov",
"cmp",
"add",
"sub",
"not",
"clr",
"lea",
};
for( size_t i = 0; i < sizeof(typtbl)/sizeof(char*); ++i )
{
char *ptr = typtbl[i];
if(strcmp(ptr, token) == 0)
{
return i; // found something
}
}
return -1; // found nothing
}
A cleaner working version.
Main issue is in the (char *)(typtbl+i) replaced by typtbl[i] in the following code. typtbl+i is equivalent to &typtbl[i], so if my memory is good, it's a pointer on the pointer of the string and not the pointer of string itself
I added a NULL at the end of the array to be able to stop if the string is not present and return -1 to clearly say it was not found.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int what(char *token);
int main()
{
int i = 0;
char string[] = "jsr";
i = what(string);
printf(" location of input is %d \n", i);
return 0;
}
int what(char *token)
{
char *typtbl[] = {
"mov",
"cmp",
"add",
"jsr",
"not",
"clr",
"lea",
NULL
};
int i = 0;
while(typtbl[i] && !(strcmp(typtbl[i], token) == 0)) {
++i;
}
if(!typtbl[i])
i = -1;
return i;
}
char *token; token=&string[0]; was useless because string == &string[0].
A few things:
Your main function is missing its return type.
The while loop in what doesn't stop when the element isn't found. Therefore you are reading out of bounds.
This should do the work w/o pointer arithmetic.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int what (char * token);
int main(){
int i=0;
char string[]="jsr";
char *token;
token=&string[0];
i=what(token);
printf(" location of input is %d \n", i);
return 0;
}
int what (char * token){
unsigned int i=0;
char *typtbl[]={"mov",
"cmp",
"add",
"sub",
"not",
"clr",
"lea",
};
unsigned int typtbl_x_size = sizeof(typtbl)/sizeof(typtbl[0]);
char * ptr;
ptr=typtbl[i];
while (!(strcmp(ptr,token)==0)){
i += 1;
if (i >= typtbl_x_size){
printf("element not in list\n");
return -1;
}
ptr=typtbl[i];
}
return i;
}

How to pass 2d array of string to the function and print value of it?

Why it is not working... It should be working, right? gcc have problem with this line, but why?
render_history(history, 2);
Sorry for bothering. I am just a beginner.
#include <stdio.h>
void render_history(char** history, const int entry);
int main()
{
char* history[3][4];
history[0][0] = "1234";
history[1][0] = "5678";
history[2][0] = "9012";
render_history(history, 2); //??
return 0;
}
void render_history(char** history, const int entry)
{
// print "9012"
}
gcc have problem with this line, but why?
Because the type is wrong. char* history[3][4]; can't be passed as char**. They are incompatible types.
Try something like:
#include <stdio.h>
void render_history(char* (*history)[4] , const int entry)
{
printf("%s\n", history[entry][0]);
}
int main()
{
char* history[3][4];
history[0][0] = "1234";
history[1][0] = "5678";
history[2][0] = "9012";
render_history(history, 2);
return 0;
}
As mentioned above double pointer not equal to 2D array.
You can also use pointer to pointer of char. char **history. And with this you have several option:
1) Use compound literals
#include <stdio.h>
void render_history(const char **history, const int entry)
{
printf("%s\n", history[entry]);
}
int main(void)
{
const char **history = (const char *[]) { "1234", "5678", "9012", NULL};
render_history(history, 2);
return 0;
}
If you need change your data later
2) Use dynamic memory allocation with malloc
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void render_history(char **history, const int entry)
{
printf("%s\n", history[entry]);
}
int main(void)
{
char **history = malloc(3 * sizeof(char *));
for (int i = 0; i < 3; ++i)
{
history[i] = malloc(4 * sizeof(char));
}
strcpy(history[0], "1234");
strcpy(history[1], "5678");
strcpy(history[2], "9012");
history[3] = NULL;
render_history(history, 2);
return 0;
}
If you use 2nd option dont forget free memory after use.

C programming : Creating substring

I'm new in C and I need some explanation on what I am doing wrong.
I'm trying to iterate over a string and find the first '\' then make a substring from that place in the array.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
struct info{
char* name;
char* type;
char* path;
};
struct info user1;
char* a = "/home/users/user1";
for (int i = strlen(a) ; i < 0 ; i--) {
printf("%d",i);
if(strcmp(a[i],'/')==0){
strncpy(a,user1.name,i);
break;
}
}
return 0;
}
There are many errors I will explain them one by one. The code will be something like this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
struct info{
char* name;
char* type;
char* path;
};
struct info user1;
user1.name = malloc(40);
if( user1.name == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
const char* a = "/home/users/user1";
for(int i = strlen(a) -1; i >= 0 ; i--) {
if(a[i]=='/'){
strncpy(user1.name,a+i+1,i);
user1.name[i]='\0';
break;
}
}
printf("%s\n",user1.name );
free(user1.name);
return 0;
}
Things you did wrong
There was no memory allocated to name it was simply an uninitialized pointer. Here we have allocated memory to it.
Second thing, strcmp as the name suggests compares null terminated char array not char-s. It can be done with simple == operator.
The copy part is modified to only copy the user name part nothing else. That's why we have incremented the pointer to point to the correct position.
You forgot to check the return value of malloc and then you should free the allocated memory.
Also you can't modify a string literal because it stays in non-modifiable portion of the memory.
try this,
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
struct info{
char* name;
char* type;
char* path;
};
struct info user1;
user1.name = malloc(10);
char* a = "/home/users/user1";
int len=strlen(a);
for (int i = 0; i < len; i++) {
printf("%d",i);
if(a[i]=='/'){
strncpy(user1.name,a+i+1,i);
user1.name[i]='\0';
break;
}
}
return 0;
}

List with struct pointer

I have the following code but the result is null for all components of the structure:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _TransactionType
{
char field1[20];
char field2[20];
}TransactionType;
int main(int argc, char *argv[]) {
int i;
int numreg = 0;
char temp[12];
TransactionType *dbTransaction;
dbTransaction = (TransactionType*) calloc(10,sizeof(TransactionType));
for(i=0; i<5;i++)
{
memset(temp,0,sizeof(temp));
sprintf(temp,"%d",i);
strcpy(dbTransaction->field1, temp);
dbTransaction->field1[strlen(dbTransaction->field1)] = '\0';
strcpy(dbTransaction->field2, temp);
dbTransaction->field2[strlen(dbTransaction->field2)] = '\0';
numreg++;
dbTransaction++;
}
printf("reg = %d\n", numreg);
for (i=0; i<numreg;i++)
{
printf("dbTransaction->field1 = %s\n",(dbTransaction + i)->field1);
printf("dbTransaction->field2 = %s\n",(dbTransaction + i)->field2);
}
return 0;
}
i need to recover the structure values.
Please any kind of help will be appreciate
Thanks in advance for your help
You should add error checking and casting of calloc values is discouraged, but the reason your code doesn't work is that you advance dbTransaction pointer in your loop, but never rewind it. The prints you're making are actually of elements 5-9 of the array while you fill elements 0-4.
See the corrected code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _TransactionType
{
char field1[20];
char field2[20];
}TransactionType;
int main(int argc, char *argv[]) {
int i;
int numreg = 0;
char temp[12];
TransactionType *dbTransaction;
TransactionType *dbTransactionRoot;
dbTransaction = (TransactionType*) calloc(10,sizeof(TransactionType));
dbTransactionRoot = dbTransaction;
for(i=0; i<5;i++)
{
memset(temp,0,sizeof(temp));
sprintf(temp,"%d",i);
strcpy(dbTransaction->field1, temp);
dbTransaction->field1[strlen(dbTransaction->field1)] = '\0';
strcpy(dbTransaction->field2, temp);
dbTransaction->field2[strlen(dbTransaction->field2)] = '\0';
numreg++;
dbTransaction++;
}
printf("reg = %d\n", numreg);
for (i=0; i<numreg;i++)
{
printf("dbTransaction->field1 = %s\n",(dbTransactionRoot + i)->field1);
printf("dbTransaction->field2 = %s\n",(dbTransactionRoot + i)->field2);
}
return 0;
}

qsort of struct array not working

I am trying to sort a struct run array called results by a char, but when I print the array, nothing is sorted. Have a look at this:
struct run {
char name[20], weekday[4], month[10];
(And some more...)
};
typedef struct run run;
int name_compare(const void *a, const void *b)
{
run *run1 = *(run **)a;
run *run2 = *(run **)b;
return strcmp(run1->name, run2->name);
}
int count_number_of_different_persons(run results[])
{
int i = 0;
qsort(results, sizeof(results) / sizeof(run), sizeof(run), name_compare);
for(i = 0; i <= 999; i++)
{
printf("%s\n", results[i].name);
}
// not done with this function yet, just return 0
return 0;
}
The output from the above is just a list of names in the order they were originally placed
int count_number_of_different_persons(run results[])
This doesn't really let you use sizeof on the array, because array is decayed to pointer.
This
run *run1 = *(run **)a;
also looks weird, shouldn't it be
run *run1 = (run*)a;
?
One problem is in name_compare. Try this instead:
int name_compare(const void *a, const void *b)
{
run *run1 = (run *)a;
run *run2 = (run *)b;
return strcmp(run1->name, run2->name);
}
Check the following code:
As #michel mentioned, sizeof(array) provides size of the pointer, not the size of the array itself, as while passing array it is treated as a pointer. Hence either send the number of elements to the function count_number_of_different_persons or define a MACRO of number of elements. Hope this helps. :).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NOE 3
struct run
{
char name[20];
};
typedef struct run run;
int name_compare (const void *a, const void *b )
{
return strcmp (((run *)a)->name, ((run *)b)->name);
}
int count_number_of_different_persons(run results[], int noOfElements)
{
int i=0;
qsort(results, noOfElements, sizeof (run), name_compare);
for (i=0; i<noOfElements; i++)
printf ("%s\n",results[i].name);
}
int main ( int argc, char * argv[])
{
run a, b, c;
run arg[NOE];
strcpy (a.name, "love");
strcpy (b.name, "you");
strcpy (c.name, "i");
arg[0] = a;
arg[1] = b;
arg[2] = c;
count_number_of_different_persons(arg, sizeof(arg)/sizeof(run));
};

Resources