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;
}
Related
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHARS 10
char **readText(void) ;
typedef struct text_t
{
char * * mt;
int words;
}
Text_t;
int main(void)
{
int i, words;
Text_t.mt = readText();
for (i=0; i<words; i++)
printf("%s\n", Text_t.mt[i]);
return 0;
}
char **readText(void)
{
*Text_t.mt = NULL;
char *word;
*words = 0;
while (scanf("%s", word=malloc(CHARS*sizeof(char))),
strcmp(word,"END"))
{
(*words) ++;
Text_t.mt = realloc(mytext, (*words)*sizeof(char *));
Text_t.mt[*words-1] = word;
}
free(word);
return Text_t.mt;
}
The goal of this programm is to take some words as input from the user untill the word "END" is entered. Then we print the given words with the same order as they were entered. The problem is when I try to run the programm, this error comes up:
main.c|16|error: expected identifier or '(' before '.' token|
You probably mean
Text_t tt;
tt.mt = NULL;
ie
create an instance ot the Text_t struct
set its 'mt' pointer to NULL
whether thats the correct thing for your main aim I cant say, but at least it will get you past your current compile error
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;
}
I want to parse a string into an array of tokens . '\n' and ';' are delimiters , for e.g. :
hello;hello
world
should be converted to an array containing: {"hello","hello","world"}.
I tried many different methods for doing this and always I fail (since it needs a dynamic array of char * I have trouble with implementing it).
Please note that I cannot use strtok or lexical analyzer.
How may I do this ? Any points ?
EDIT : here is one of methods I tried to use but I get segmentation fault (maybe a memory access issue somewhere in my code) :
#include <stdio.h>
#include <malloc.h>
#include <fcntl.h>
#include <string.h>
typedef struct {
int fd;
char *path;
int size;
char *mem;
struct stat st;
} file;
file *readfile(char *path) {
file *a=malloc(sizeof(file));
a->path=path;
a->fd=open(a->path,O_RDONLY);
if(a->fd<0) return 0;
fstat(a->fd,&a->st);
a->size=a->st.st_size;
a->mem=malloc(a->size);
read(a->fd,a->mem,a->size);
return a;
}
void releasefile(file *a) {
free(a->mem);
close(a->fd);
free(a);
}
char **parse(int *w,file *a) {
int i,j=0;
w=0;
for(i=0;i<=a->size;i++) {
if(a->mem[i]=='\n' || a->mem[i]==';') { a->mem[i]='\0'; j++; }
}
char **out=malloc(sizeof(char *)*j);
for(i=0;i<=a->size;i++) {
if(a->mem[i-1]!='\0') continue;
out[*w]=malloc(strlen(a->mem+i)+1);
memcpy(out[*w],a->mem+i,strlen(a->mem+i)+1);
w++;
return out;
}
int main(int argc,char **argv) {
file *a=readfile(argv[1]);
int *w=malloc(sizeof(int));
char **tokens=parse(w,a);
int i;
for(i=0;i<=*w;i++) {
puts(tokens[i]);
}
releasefile(a);
// ATM no need to check for mem leaks :)
}
Algorithm description : read file, put \0 where you see a delimiter, start and push tokens seprated by \0 into an array.
What has happened to computer science?
Anyway write a FSA - http://en.wikipedia.org/wiki/Finite-state_machine
Can do this using a table
I'm trying to create an array of structures, but I'm not sure how to proceed with declaring an array and mallocing it. Here is the code I have so far:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_STRING 128
typedef char String[MAX_STRING]
typedef struct {
String Name; //Name of the person
String Best; //Name of the best friend
} Names;
int main(void) {
}
This is an exercise I'm trying to do and the end product should be like this: HERE
#include <stdlib.h>
#include <stdio.h>
#define N 3
typedef struct
{
char* Name; //Why complicate things using a string?
char* Best;
}Names;
int main(void)
{
int i;
//Create an array of pointers.
//Each element of the array is a pointer to a struct "Names"
Names** data = malloc(N*sizeof(Names*));
//data[i] is a array element which points to a single struct "Names".
//Dynamically allocate memory for each struct
for(i=0;i<N;i++)
{
data[i] = malloc(sizeof(Names));
}
//Rest is your assignment
data[0]->Name = "aaaa";
data[0]->Best = "bbbb";
data[1]->Name = "cccc";
data[1]->Best = "dddd";
data[2]->Name = "eeee";
data[2]->Best = "ffff";
for(i=0;i<N;i++)
{
printf("%s\t%s\n",data[i]->Name,data[i]->Best);
}
}
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define MAX_STRING 128
#define NUMBER_OF_STRUCTURES_IN_ARRAY 10
typedef char String[MAX_STRING]
typedef struct {
String Name; //Name of the person
String Best; //Name of the best friend
} Names;
int main(void)
{
int rCode=0;
Names *names_A = NULL;
int index;
names_A = malloc(sizeof(*names_A) * NUMBER_OF_STRUCTURES_IN_ARRAY);
if(NULL == names)
{
rCode=ENOMEM;
fprintf(stderr, "Error: malloc() failed\n");
goto CLEANUP;
}
for(index=0; index < NUMBER_OF_STRUCTURES_IN_ARRAY; ++index)
{
strcpy(names_A[index].Name, "Some Name");
strcpy(names_A[index].Best, "Another Name");
}
CLEANUP:
if(names_A)
free(names_A);
return(rCode);
}
This question already has answers here:
Passing address of array as a function parameter
(6 answers)
Closed 9 years ago.
I'm writing a function that gets a string, allocates memory on the heap that's enough to create a copy, creates a copy and returns the address of the beginning of the new copy.
In main I would like to be able to print the new copy and afterwards use free() to free the memory. I think the actual function works although I am not the char pointer has to be static, or does it?
The code in main does not work fine...
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int make_copy(char arr[]);
int main()
{
char arrr[]={'a','b','c','d','e','f','\0'};
char *ptr;
ptr=make_copy(arrr);
printf("%s",ptr);
getchar();
return 0;
}
int make_copy(char arr[])
{
static char *str_ptr;
str_ptr=(char*)malloc(sizeof(arr));
int i=0;
for(;i<sizeof str_ptr/sizeof(char);i++)
str_ptr[i]=arr[i];
return (int)str_ptr;
}
OK, so based on the comments. A revised version:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={"abcdef\0"};
char *ptr=make_copy(arrr);
printf("%s",ptr);
getchar();
return 0;
}
char* make_copy(char arr[])
{
static char *str_ptr;
str_ptr=(char*)malloc(strlen(arr)+1);
int i=0;
for(;i<strlen(arr)+1;i++)
str_ptr[i]=arr[i];
return str_ptr;
}
Or even better:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={"abcdef\0"};
printf("%s",make_copy(arrr));
getchar();
return 0;
}
char* make_copy(char arr[])
{
char *str_ptr;
str_ptr=(char*)malloc(strlen(arr)+1);
return strcpy(str_ptr,arr);
}
You're on the right track, but there are some issues with your code:
Don't use int when you mean char *. That's just wrong.
Don't list characters when defining a string, write char arrr[] = "abcdef";
Don't scale string alloations by sizeof (char); that's always 1 so it's pointless.
Don't re-implement strcpy() to copy a string.
Don't cast the return value of malloc() in C.
Don't make local variables static for no reason.
Don't use sizeof on an array passed to a function; it doesn't work. You must use strlen().
Don't omit including space for the string terminator, you must add 1 to the length of the string.
UPDATE Your third attempt is getting closer. :) Here's how I would write it:
char * make_copy(const char *s)
{
if(s != NULL)
{
const size_t size = strlen(s) + 1;
char *d = malloc(size);
if(d != NULL)
strcpy(d, s);
return d;
}
return NULL;
}
This gracefully handles a NULL argument, and checks that the memory allocation succeeded before using the memory.
First, don't use sizeof to determine the size of your string in make_copy, use strlen.
Second, why are you converting a pointer (char*) to an integer? A char* is already a pointer (a memory address), as you can see if you do printf("address: %x\n", ptr);.
sizeof(arr) will not give the exact size. pass the length of array to the function if you want to compute array size.
When pass the array to function it will decay to pointer, we cannot find the array size using pointer.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *strdup(const char *str)
{
char *s = (char*)malloc(strlen(str)+1);
if (s == NULL) return NULL;
return strcpy(s, str);
}
int main()
{
char *s = strdup("hello world");
puts(s);
free(s);
}
Points
~ return char* inside of int.
~ you can free the memory using below line
if(make_copy!=NULL)
free(make_copy)
Below is the modified code.
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={'a','b','c','d','e','f','\0'};
char *ptr;
ptr=make_copy(arrr,sizeof(arrr)/sizeof(char));
printf("%s",ptr);
printf("%p\n %p",ptr,arrr);
getchar();
return 0;
}
char* make_copy(char arr[],int size)
{
char *str_ptr=NULL;
str_ptr=(char*)malloc(size+1);
int i=0;
for(;i<size;i++)
str_ptr[i]=arr[i];
str_ptr[i]=0;
return str_ptr;
}