I am trying to run the following code:
Main C file:
#include <stdio.h>
#include "my_functions.c"
#include "my_functions.h"
int main(int argv, char ** argc) {
for (int i = 0; i < argv; i++)
printf("%s\n", argc[i]);
printf("%d\n", str_find("=","-h=123"));
printf("%d\n",str_find("xyx", "aaaa"));
return 0;
}
Included .c file for Main .c file from local Library / my_functions.c file
#include <stdio.h>
#include "my_functions.h"
int str_length(char* mystring){
int i=0;
while(*mystring!='\0'){
i++;
mystring++;
}
return i;
}
Included .h file for Main .c file from local Library / my_functions.h file
#ifndef MyFunctions_h
#define MyFunctions_h
#include <stdio.h>
void str_copy(char *destination, char *source){
while(*source != '\0'){
*destination = *source;
source++;
destination++;
}
*destination = '\0';
}
#endif
int str_find(char* needle, char* haystack) {
int i = 0;
int c = 0;
while(*needle!='\0'){
++i;
++needle;
}
needle -= i;
while(*haystack!='\0'){
++c;
++haystack;
}
haystack -= c;
int k=0;
int sp = 0;
for(int d=0; d<=c; ++d, ++haystack)
{
if(*haystack==*needle && k==0)
{
sp = d;
++k;
++needle;
}else if(*haystack!=*needle && k != 0)
{
needle -= k;
k = 0;
}
}
if(sp==0){
return -1;
}else{
return sp;
}
}
Here is the error I am receiving in the Output in Visual Studio Code, which comes from the imported my_functions.h file and the int str_find(char* needle, char* haystack) function :
redefinition of 'int str_find(char*, char*)'
I am unable to resolve this issue on my own and need help.
What needs to be done to solve this issue, so my code can run properly?
The problem is that you did not guard declaration of the str_find.
main.c includes my_functions.c that includes my_functions.h and therefore declares str_find.
After that, you include my_functions.h that declares str_find again.
To fix that just move #endif to the bottom of my_functions.h
Related
I was working on pop and push methods on the stack. Actually in this code I am creating dynamic array using pointers and malloc function. Then I was trying to add or delete elements to dynamic array with pop and push methods.But I getting the error in the question. I can't see any error in the code. Can you help me?
Here my main.c file
#include <stdio.h>
#include <stdlib.h>
#include "main_header.h"
stack * init(){
stack *s = (stack *) malloc(sizeof(stack));
s->items = NULL;
s->top = 0;
s->count = 2;
return s;
}
int pop(stack *s){
if(s->items == NULL){
printf("Items is empty.\n");
return -1;
}
if(s->top<=s->count/4){
int *items2 = (int *)malloc(sizeof(int)*s->count/2);
for (int i = 0; i < (s->count/2); i++){
items2[i] = s->items[i];
}
free(s->items); // burada "dizi" adındaki dizimiz dizi2 ile aynı yeri gösterdiğinde önceki 2 elemanlık dizi lost in space olacak bunu önlemek için free(dizi) diyerek o 2 elemanı bellekten siliyoruz.
s->items = items2;
s->count /= 2;
}
return s->items[--s->top];
}
void push(int a, stack *s){
if(s->items == NULL){
s->items = (int *)malloc(sizeof(int) * 2);
}
if(s->top>=s->count){
int *items2 = (int *)malloc(sizeof(int)*s->count*2);
for (int i = 0; i < s->count; i++)
items2[i] = s->items[i];
free(s->items); // burada "dizi" adındaki dizimiz dizi2 ile aynı yeri gösterdiğinde önceki 2 elemanlık dizi lost in space olacak bunu önlemek için free(dizi) diyerek o 2 elemanı bellekten siliyoruz.
s->items = items2;
s->count *= 2;
}
s->items[s->top++] = a;
}
void getItems(stack *s){
printf("count: %d\n", s->count);
for (int i = 0; i < s->top; i++) {
printf("%d\n", s->items[i]);
}
}
main_header.h file
#ifndef main
#define main
struct s {
int count;
int top;
int *items;
};
typedef struct s stack;
stack * init(void);
int pop(stack *);
void getItems(stack *);
void push(int, stack *);
#endif
test_stack.c file
#include <stdio.h>
#include <stdlib.h>
#include "main_header.h"
int main(){
stack *s1 = init();
stack *s2 = init();
for (int i = 0; i < 10; i++) {
push(i*10, s1);
}
getItems(s1);
for (int i = 0; i < 10; i++) {
push(pop(s1), s2);
}
return 0;
}
After #define main in “main_header.h”, the code int main(){ in “test_stack.c” is replaced by int (){. This causes the syntax error that the compiler (not Xcode) reports.
Do not use main in “main_header.h” as an indicator for whether the header file has been included already. Use some other name that you will not use for anything else, such as main_h or main_header_h.
(Clang is the compiler. Xcode is the overall integrated development environment that facilitates use of the compiler, organizes your projects files, opens editors, maintains your project options, and so on.)
How can I call this convert function using command line and from argument 2 onwards start converting the strings to int and store in an array?
#include <stdio.h>
int main (int argc , char* argv[])
{
int i;
if (argc < 2)
{
printf("Error: Less than two arguments\n");
}
else
{
for(i=0; i<argc; i++)
{
printf("[%d] : %s\n", i , argv[i]);
}
}
return 0;
}
Function in the same directory but in a separate C file:
void convert ( char* parray[] ,int array[] )
{
int i;
printf("The converted array = ");
for (i=0; i< LENGTH; i++)
{
array[i] = atoi(parray[i]);
printf(" %d" , array[i]);
}
printf("\n");
}
You can compile both files into the same executable, e.g like:
gcc -o main main.c convert.c
To use the function in convert.c in main.c, you will have to declare the function before you define the main() function, like this:
#include<stdio.h>
void convert ( char* parray[] ,int array[] );
int main (int argc , char* argv[])
{
// your code ..
//you may now use the convert function inside the main function
convert(param1, param2);
}
Alternatively, you could create a header file for convert.c, called convert.h, like this:
#ifndef CONVERT_H
#define CONVERT_H
void convert ( char* parray[] ,int array[] );
#endif
Then, you could include the headerfile in the main file like this:
#include<stdio.h>
#include "convert.h"
int main (int argc , char* argv[])
{
// use convert here somewhere
convert(param1, param2);
}
Create a module, have the declarations in a separate file, and the implementations in a separate.
functions.h:
#ifndef FUNCTIONS_H /* include guard */
#define FUNCTIONS_H
void convert(char *parray[], int array[], int length);
#endif
functions.c:
#include "functions.h" /* include your header with the declarations */
#include <stdio.h>
#include <stdlib.h>
void convert(char *parray[], int array[], int length)
{
int i;
printf("The converted array = ");
for (i = 0; i < length; i++)
{
array[i] = atoi(parray[i]);
printf(" %d", array[i]);
}
printf("\n");
return;
}
main.c:
#include "functions.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i, *arr = NULL;
if (argc < 2)
{
printf("Error: Less than two arguments\n");
}
else
{
arr = malloc((argc - 1) * sizeof(int)); /* array can be static too */
if (arr == NULL)
{
exit(EXIT_FAILURE);
/* handle error */
}
convert(&argv[1], arr, argc - 1);
free(arr); /* free when you exit */
}
return 0;
}
Compilation:
clang -c functions.c && clang main.c functions.o
OR
clang functions.c main.c
Output:
$ ./a.out 15 20 -90 18 20 20 8 8 8 81
$ The converted array = 15 20 -90 18 20 20 8 8 8 81
I'm trying to parse a json file using jsmn but I get segmentation fault when I run my application. I'm using C and compiling on Ubuntu machine.
Please find the code snippet below:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "jsmn.h"
#define JSON_FILE_PATH "/home/admin/Desktop/test/server/dataFile.json"
#define BUFFER_SIZE 5000
#define MAX_TOKEN_COUNT 128
// Read files
void readfile(char* filepath, char* fileContent)
{
FILE *f;
char c;
int index;
f = fopen(filepath, "r");
***while((c = fgetc(f)) != EOF){*** ------> seg fault
fileContent[index] = c;
index++;
}
fileContent[index] = '\0';
}
// This is where the magic happens
int parseJSON(char *filepath, void callback(char *, char*)){
char JSON_STRING[BUFFER_SIZE];
char value[1024];
char key[1024];
readfile(filepath, JSON_STRING);
int i;
int r;
jsmn_parser p;
jsmntok_t t[MAX_TOKEN_COUNT];
jsmn_init(&p);
r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t, sizeof(t)/(sizeof(t[0])));
if (r < 0) {
printf("Failed to parse JSON: %d\n", r);
return 1;
}
/* Assume the top-level element is an object */
if (r < 1 || t[0].type != JSMN_OBJECT) {
printf("Object expected\n");
return 1;
}
for (i = 1; i < r; i++){
jsmntok_t json_value = t[i+1];
jsmntok_t json_key = t[i];
int string_length = json_value.end - json_value.start;
int key_length = json_key.end - json_key.start;
int idx;
for (idx = 0; idx < string_length; idx++){
value[idx] = JSON_STRING[json_value.start + idx ];
}
for (idx = 0; idx < key_length; idx++){
key[idx] = JSON_STRING[json_key.start + idx];
}
value[string_length] = '\0';
key[key_length] = '\0';
callback(key, value);
i++;
}
return 0;
}
// Only prints the key and value
void mycallback(char *key, char* value){
printf("%s : %s\n", key, value);
}
int main()
{
parseJSON(JSON_FILE_PATH, mycallback);
return 0;
}
I get segmentation fault after the line as indicated when the file operation of reading is done.
On debugging, at this point f contains 0x00 value which means it is not able to identify the file.
Why this might be happening when file is present at that location?
I tried changing paths but still same issue.
Found the solution:
index is not initialized before use
char c should be int c - fgetc returns an int
why can't I use #include "getline.c" or strindex.c in vc 6.0?
-----test30src.c------
#include <stdio.h>
#include "getline.c"
#include "strindex.c"
#define MAXLINE 1000
char pattern[] = "ould";
int main()
{
char line[MAXLINE];
int found = 0;
while(getline(line, MAXLINE) > 0)
if(strindex(line, pattern) >= 0){
printf("%s", line);
found++;
}
return found;
}
------getline.c------
#include <stdio.h>
int getline(char s[], int lim)
{
int c, i;
i = 0;
while(--lim > 0 && (c = getchar()) != EOF && c != '\n')
s[i++] = c;
if(c=='\n')
s[i++] = c;
s[i] = '\0';
return i;
}
-----strindex.c-----
int strindex(char s[], char t[])
{
int i, j, k;
for(i = 0; s[i] != '\0'; i++){
for(j = i, k = 0; s[j] == t[k]; j++, k++)
;
if(k > 0 && t[k] == '\0')
return j;
}
return -1;
}
Error:
--------------------Configuration: test30 - Win32 Debug--------------------
Linking...
getline.obj : error LNK2005: _getline already defined in test30src.obj
strindex.obj : error LNK2005: _strindex already defined in test30src.obj
Debug/test30.exe : fatal error LNK1169: one or more multiply defined symbols found
You should include string.h instead of getline.c
You must not include files which contain definitions, or you will end up with multiple instances of the same functions. Create header file which contains only declarations.
getline.c (definitions)
#include "getline.h"
int getline(char s[], int lim) { ... }
getline.h (only declarations)
#ifndef GETLINE_H
#define GETLINE_H
int getline(char s[], int lim);
#endif
main.c (include only header)
#include "getline.h"
Most IDEs will compile all .c files by default. Here, it will compile once getline.c
and strindex.c by themselves, and a second time when it compiles testsrc30.c, which include the two other files. Remember that the #include directive simply copy the contents of the included file.
At the time of linking, some symbols are found twice, and the linker can't handle the ambiguity-
The standard way of using #include's is with header (.h) files containing the declarations for your functions.
Example
//getline.h
#ifndef GETLINE_H //Header guard - avoid multiple inclusion
#define GETLINE_H
#include <stdio.h>
int getline(char s[], int lim); //function declaration
#endif // GETLINE_H
.
//getline.c
#include "getline.h"
int getline(char s[], int lim) //declaration
{
// Implement whatever your function does
}
.
// test30src.c
#include "getline.h"
int main(void)
{
// Put your code here
}
In some cases, it might be tolerable to include .c files. But in this case, you should make sure that these .c files are not compiled by themselves and linked. See this related question : Including one C source file in another?
you can include c files like this but make sure to put those files in the same directory or else give full path.
#include "complete_path/getline.c"
this will work
I am very beginner to work with dll and linking various file.
I just know write main() function and all other in same .c file and run it.
I have one program which works for pattern matching. It takes the string and check whether it exist in entire text string or not. like
Text string: my name is john
string to be matched: name
Answer: Yes
main function is like this:
int main(int argc, const char *argv[])
{
char target[200];
char *ch = target;
char pattern[20];
int i,k,count,l;
printf("\nEnter the string: \n");
fgets(target,100,stdin);
printf("Enter the string to be matched: \n");
fgets(pattern,20,stdin);
l=strlen(pattern);
i = kmp(target, strlen(target)-1, pattern, strlen(pattern)-1);
//printf("I is : %d\n",i);
if (i == -1)
puts("False");
else
puts("True");
getch();
return 0;
}
Which calls function kmp() and get result back. We can also print the result in kmp() function. kmp() function is as follow:
int kmp(char *target, int tsize, char *pattern, int psize)
{
int i;
int *pi = compute_prefix_function(pattern, psize);
int k = -1;
if (!pi)
return -1;
for (i = 0; i < tsize; i++) {
while (k > -1 && pattern[k+1] != target[i])
k = pi[k];
if (target[i] == pattern[k+1])
k++;
if (k == psize - 1) {
free(pi);
return i-k;
}
}
free(pi);
return -1;
}
In kmp we call compute_prefix_function(pattern, psize); which is as below:
int *compute_prefix_function(char *pattern, int psize)
{
int k = -1;
int i = 1;
int *pi = malloc(sizeof(int)*psize);
if (!pi)
return NULL;
pi[0] = k;
for (i = 1; i < psize; i++) {
while (k > -1 && pattern[k+1] != pattern[i])
k = pi[k];
if (pattern[i] == pattern[k+1])
k++;
pi[i] = k;
}
return pi;
}
Header files need to be called:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
What I want to do is:
Creating an implementations in a dll/shared library format. essentially, the dll should have a function extension which take a string and return a bool saying if the string exists or not.
For that which function I need to put in .c file and header file and how to create .dll file for this?
I am using windows 7, VS 2010 and C programming.
Please explain me step by step.
I'll say more about the DLL further down, but for a start, here is the layout of the source files you'll need to do that.
You'll need three files:
main.c
kmp.h
kmp.c.
Code structure:
File main.c
#include <stdio.h>
#include "kmp.h" // this will make the kmp() function known to main()
int main(int argc, const char *argv[])
{
char target[200];
... same code as you aready have
}
File kmp.h
// prototype to make kmp() function known to external programs (via #include)
extern int kmp(char *target, int tsize, char *pattern, int psize);
File kmp.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// declare kmp prototype as DLL-export
_declspec(dllexport) int kmp(char *target, int tsize, char *pattern, int psize);
// prototype for internal helper function
static int *compute_prefix_function(char *pattern, int psize);
//
// implementation of kmp() function (and helper)
//
int kmp(char *target, int tsize, char *pattern, int psize)
{
int i;
... same program code as you aready have
}
int *compute_prefix_function(char *pattern, int psize)
{
int k = -1;
... same program code as you aready have
}
.
Now, for a first step, you can make these three files, and compile them in your current project (i.e. split your current project source into those three files, just leave out the line in kmp where it says __declspec(dllexport) and compile as before (non-DLL) to see if all works).
.
You will then need to create a DLL project for kmp.h and kmp.c (that will compile a KMP.DLL and KMP.LIB). Then you create a normal program (like your current sample) with main.c and need to link it with KMP.LIB / KMP.DLL
The following may be a bit fuzzy, because I only have VS2005 here, but the steps to create the DLL project should be essentially somewhat like this:
new project: Type Win32 / Win32-Project
name KMP
in the wizard choose Type DLL and check "Empty Project"
add your kmp.c and kmp.h files
In your main project (the one with the main.c program), you can then do
File Menu > Add > Existing Project > KMP.vcproj
This will automatically build and link the DLL from with your main.c program project.