Whats wrong with the given code - c

I am just learning some pointers stuff in C and I happened to learn that using the * one can dereference the pointer. So I wrote the following code to check for that.
#include<stdio.h>
#include<string.h>
char *findChar(char *s, char c){
while(*s!=c){
s++;
}
return s;
}
int main(){
char myChar='a';
const char myString[]="Hello abhishek";
char *location;
location = findChar(myString,myChar);
puts(location);
char temp = *location;
printf(temp);
}
I assume that temp should get the value pointed by the character pointer location, But this program is giving me a segmentation fault. Please clearify what I am doing wrong?

The following is incorrect:
char temp = *location;
printf(temp);
If you want to print out the char, use the following:
char temp = *location;
printf("%c\n", temp);
The first argument to printf() should be the format string.

The first argument of printf should be char* (for the format), not char.
Try printf("%c\n",temp);
By the way, to see the index of myChar in the array, you may want to print location-myString

The printf causes the segmentation fault, as printf expects a char pointer for temp and you pass a single char to it.

Related

Spliting string and storing in array or pointer in C

I'm working in a little project, i have some names stored in a struct (example: Name1, Name2) and I need to split each one and store it in a array so I can call then each name separately (printf("%s", vet[1]) should print only "Name2").
This is my code:
int main(){
char temp[100];
LIGA *vetLiga;
int reference;
int quantiy;
separarEquipas(vetLiga, temp, reference, quantity);
}
int separarEquipas(LIGA *p, char vet[100], int vPesquisa, int n){
int i, nr, a;
char *ptr;
char *str;
for(i=0;i<n;i++){
if (p->id == vPesquisa){
nr = p->nrEquipas;
strcpy(str, p[i].eqLiga);
ptr = strtok(str, " ,");
while(ptr != NULL)
{
vet[a++] = ptr; //here I'm trying to store each word in a position of the array
ptr = strtok(NULL, " ,");
}
}
p++;
}
return nr;
}
The issue is inside the while where I try to store each token in the array but it keeps crashing the terminal. I tried in different ways like using strcpy and memcpy as other posts suggest but nothing :(.
Some errors that i got while trying to find a solution:
[Warning] assignment makes integer from pointer without a cast;
[Warning] passing argument 1 of 'strcpy' makes pointer from integer without a cast.
Hope you can help me,
Thank you!
You didn't post the full code, so from what I can see vetLiga that in separarEquipas becomes p is uninitialised.
Another issue is that you try to use str in strcpy without allocating memory for it. You need to do that
char *str = malloc( max_number_of_characters_in_str );
Then here:
vet[a++] = ptr; //here I'm trying to store each word in a position of the array
You are doing exactly what you said in the comment. However you can't store a word into the space for a single character. vet needs to be a 2D array or if you want even an array of pointers to char.
If you want further help include the whole program.
In main, vetLiga is never assigned a value, but maybe you abbreviated the code.
In separarEquipas you have the following:
char *str;
strcpy(str, p[i].eqLiga)
So you are copying a string to a random location in memory.

Double dimension array, attribute value but can't read from it later

I'm passing values beteween childs and need to store some values to later use.
the definitions and use in functions
char fouts[MAX_SIZE][10];
the function where i give the array the values:
void connect(char *nodo, char *out[], int nouts) {
(...)
for(i=0;i<nouts;i++) {
fouts[fnum][i] = out[i];
}
(...)
and the function where i'm trying to use them:
void disconnect(char *nodo, char *remover){
char *outs[10];
nouts = fnouts[getfnum];
int m =0;
for(i=0;i<nouts;i++) {
if(strcmp(fouts[getfnum][i],nodo) != 0) { outs[m] = fouts[getfnum][i]; m++ ; }
}
no matter what i did to try to fixm everytime it tries to execute this last for, it gives a segmentation fault.
have tried somethings (read fouts[getfnum][0] for example directly and gives a segmentaton fault, but fouts[getfnum] gives "trash")
check the value after it been atributed fouts[fnum][i] = out[i]; here and it checks out, so i guess that part is ok).
don't know if its something obvious or not, but any help?
You are mixing char and char*.
fouts[fnum][i] is a char
and
out[i] is a char pointer
So in this line
fouts[fnum][i] = out[i];
you assign a char pointer to a char which is illegal.
And in this line
if(strcmp(fouts[getfnum][i],nodo) != 0)
you pass a char (i.e. fouts[getfnum][i]) to strcmp.
That is not legal as strcmp expects a char*
From the posted code, it is hard to tell how to fix the problems. Maybe you just need:
char* fouts[MAX_SIZE][10];

What is the issue with this C code which has a error?

It is a code written to copy one pointer to another.
ERROR is Segmentation error (core Dumped)
#include<stdio.h>
char strcp(char *,char *);
int main()
{
char *p="string",*q;
printf("%s",p);
strcp(p,q);
printf("%s",q);
return 0;
}
char strcp(char *p,char *q)
{
int i;
for(i=0;*(p+i)!='\0';i++)
*(p+i)=*(q+i);
}
char *p="string"...
strcp(p,q);
What p points to is a literal and literals are read-only. Trying to copy anything to it is forbidden (and causes a segmentation fault).
...and q is not initialized, another possible cause of the seg fault.
The problem with this algorithm is an implicit assumption it makes about pointers: char *q is not a string, it is a pointer to character. It can be treated as a string if you allocate space and place a null-terminated sequence of characters into it, but your code does not do it.
You can allocate space to q with malloc, like this:
char *p="string";
char *q=malloc(strlen(p)+1);
In addition, your version of strcpy reads null terminator from a wrong pointer, and does not null-terminate the copied string:
char strcp(char *p, char *q)
{
int i;
for(i=0;*(q+i)!='\0';i++) // <<== Fix this
*(p+i)=*(q+i);
*(p+i) = '\0'; // <<== Add this line
}
As the other answers have indicated the problem starts* with char *p="string",*q;.
The Literal "string" compiles to the equivalent:
const char foo[7] = {'s','t','r','i','n','g','\0'}; why *\0
As you might see further in you code you're trying to copy data to a const a\rray. Which is illegal.
But you're playing C, you have implicitly casted the const char foo[] to a char *p, right there during initialization.
C is not type safe because it's tightly coupled to the actual instruction on the hardware. Where types don't exist anymore, just widths. But that is for another topic.
*It's not the only flaw. I tossed in a few explanatory wiki links. Because the question shows you're a novice programmer. Keep up the work.

memcpy copies array object to character pointer in C but not vice versa

I am attempting to copy a character from an array to a character pointer by means of a function. Following is my code:
#include<stdio.h>
void pass(void* arg){
char arr[1];
arr[0]='X';
memcpy((char *)arg,arr,1);
}
void main(){
char *buf=malloc(sizeof(char));
pass(buf);
printf("%c",buf);
free(buf);
}
Here, the pointer buf prints a garbage value. I tried the reverse of the above program as follows:
#include<stdio.h>
void pass(void* arg){
char arr[1];
memcpy(arr,(char *)arg,1);
printf("%c",arr[0]);
}
void main(){
char *buf=malloc(sizeof(char));
buf[0]='X';
pass(buf);
free(buf);
}
This was successful and arr[0] prints the value as X.
Could someone clarify why does the first case fail?
You have to print *buf or buf[0] instead of buf to print the first element of the array pointed by buf.
Also note that passing data having type char* to be printed via %c in printf(), which expect data having type int, is undefined behavior due to type mismatch.
Try this:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void pass(void* arg){
char arr[1];
arr[0]='X';
memcpy((char *)arg,arr,1);
}
int main(void){
char *buf=malloc(sizeof(char));
pass(buf);
printf("%c",buf[0]);
free(buf);
return 0;
}
Your problem lies here:
char *buf=malloc(sizeof(char));
:
printf("%c",buf);
because buf is a pointer to a character, not a character. The character is *buf, or buf[0] so you can fix it with:
printf ("%c", *buf);
As an aside, it's totally unnecessary to create arr and call memcpy in the first example when you can simply do:
void pass (void* arg) {
((char*)arg)[0] = 'X';
}
Dynamic memory allocation for a character in this case is also unnecessary when you can just replace the malloc line with a simple:
char buf[1];
(and get rid of the free line, of course).

C programming strcat using pointer

I am a beginner in C. I wanted to make strcat function using pointers. I made it but don't know what is wrong with it. I used gcc compiler and it gave segmentation fault output.
#include<stdio.h>
#include<string.h>
char scat(char *,char *);
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
while(*q!='\0') printf("the concatenated string is %c",*q);
}
char *scat(char *s,char *t)
{
char *p=s;
while(*p!='\0'){
p++;
}
while(*t!='\0'){
*p=*t;
p++;
t++;
}
return p-s-t;
}
This one works:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *scat(char *,char *); /* 1: your prototype was wrong */
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
printf("cat: %s\n", q); /* 2: you can use %s to print a string */
free(q);
}
char *scat(char *s,char *t)
{
char *p=malloc(strlen(s)+strlen(t)+1); /* 3: you will have to reserve memory to hold the copy. */
int ptr =0, temp = 0; /* 4 initialise some helpers */
while(s[temp]!='\0'){ /* 5. use the temp to "walk" over string 1 */
p[ptr++] = s[temp++];
}
temp=0;
while(t[temp]!='\0'){ /* and string two */
p[ptr++]=t[temp++];
}
return p;
}
You have to allocate new space to copy at the end of s. Otherwise, your while loo[ will go in memory you don't have access to.
You shoul learn about malloc() here.
It is undefined behaviour to modify a string literal and s, and eventually p, is pointing to a string literal:
char* s = "james";
s is passed as first argument to scat() to which the local char* p is assigned and then:
*p=*t;
which on first invocation is attempting to overwite the null character an the end of the string literal "james".
A possible solution would be to use malloc() to allocate a buffer large enough to contain the concatentation of the two input strings:
char* result = malloc(strlen(s) + strlen(p) + 1); /* + 1 for null terminator. */
and copy them into it. The caller must remember to free() the returned char*.
You may find the list of frequently asked pointer questions useful.
Because p goes till the end of the string and then it starts advancing to illegal memory.
That is why you get segmentation fault.
It's because s points to "james\0", string literal & you cannot modify constant.
Change char *s="james"; to char s[50]="james";.
You need to understand the basics of pointers.
a char * is not a string or array of characters, it's the address of the beginning of the data.
you can't do a char * - char* !!
This is a good tutorial to start with
you will have to use malloc
You get a segmentation fault because you move the pointer to the end of s and then just start writing the data of p to the memory directly following s. What makes you believe there is writable memory available after s? Any attempt to write data to non-writable memory results in a segmentation fault and it looks like the memory following s is not writable (which is to expect, since "string constants" are usually stored in read-only memory).
Several things look out of order.
First keep in mind that when you want to return a pointer to something created within a function it needs to have been malloc'ed somewhere. Much easier if you pass the destination as an argument to the function. If you follow the former approach, don't forget to free() it when you're done with it.
Also, the function scat has to return a pointer in the declaration i.e. char *scat, not char scat.
Finally you don't need that loop to print the string, printf("%s", string); will take care of printing the string for you (provided it's terminated).
At first, your code will be in infinte loop because of the below line. you were supposed to use curely braces by including "p++; t++ " statements.
while(*t!='\0')
*p=*t;
though you do like this, you are trying to alter the content of the string literal. which will result in undefined behavior like segmentation fault.
A sequence of characters enclosed with in double quotes are called as string literal. it is also called as "string". String is fixed in size. once you created, you can't extend its size and alter the contents. Doing so will lead to undefined behavior.
To solve this problem , you need to allocate a new character array whose size is sum of the length of two strings passed. then append the two strings into the new array. finally return the address of the new array.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* scat(char *,char *);
void append(char *t , char *s);
int main(void)
{
char *s="james";
char *t="bond";
char *n = scat(s,t);
printf("the concatenated string is %s",n);
return 0;
}
char* scat(char *s,char *t)
{
int len = strlen(s) + strlen(t);
char *tmp = (char *)malloc(sizeof(char)* len);
append(tmp,s);
append(tmp,t);
return tmp;
}
void append(char *t , char *s)
{
//move pointer t to end of the string it points.
while(*t != '\0'){
t++;
}
while( *s != '\0' ){
*t = *s;
t++;
s++;
}
}

Resources