How can I split a string into a struct? - c

I want to get a list of all substring separated by "," and put each into a struct.
e.g if i receive "connor,michel" i want to put "connor" in struct[0].name and "michel" in struct[1].name. for now I have this:
struct crit
{
char* titre;
char* noms;
int annees;
float cote;
};
char * les_noms = (char*) malloc(sizeof(char*));
int i = 0;
char *item = strtok(noms, ",");
while(item != NULL)
{
les_noms[i++] = item;
printf("un nom = %s\n", item);
item = strtok(NULL, ",");
}
sorry for the french words.
edit: maked up my mind about les_nom

What about this?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct person
{
char *name;
};
int main()
{
struct person *persons = NULL;
int num_persons = 0;
char names[80] = "joana,cleiton,márcio,elana,joão";
const char sep[2] = ",";
char *item = strtok(names, sep);
while (item != NULL)
{
persons = realloc(persons, ++num_persons * sizeof(struct person));
persons[num_persons - 1].name = malloc(strlen(item)) + 1;
strcpy(persons[num_persons - 1].name, item);
item = strtok(NULL, ",");
}
for (unsigned int i = 0; i < num_persons; i++)
{
printf("%d: %s\n", i, persons[i].name);
}
for (unsigned int i = 0; i < num_persons; i++)
{
free(persons[i].name);
}
free(persons);
}
Or the fixed size solution:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct person
{
char *name;
};
int main()
{
char names[80] = "joana,cleiton,márcio,elana,joão";
const char sep[2] = ",";
unsigned int num_persons = 1;
for (unsigned int i = 0; i < strlen(names); i++)
{
if (names[i] == ',')
{
num_persons++;
}
}
struct person persons[num_persons];
char *item = strtok(names, sep);
for (unsigned int i = 0; item != NULL; i++)
{
persons[i].name = malloc(strlen(item) + 1);
strcpy(persons[i].name, item);
item = strtok(NULL, ",");
}
for (unsigned int i = 0; i < num_persons; i++)
{
printf("%d: %s\n", i, persons[i].name);
}
for (unsigned int i = 0; i < num_persons; i++)
{
free(persons[i].name);
}
}
You probally will need more items in the struct, it is easy, look:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct person
{
char *name;
int len_name;
int id;
};
int main()
{
char names[80] = "joana,cleiton,márcio,elana,joão";
const char sep[2] = ",";
unsigned int num_persons = 1;
for (unsigned int i = 0; i < strlen(names); i++)
{
if (names[i] == ',')
{
num_persons++;
}
}
struct person persons[num_persons];
char *item = strtok(names, sep);
for (unsigned int i = 0; item != NULL; i++)
{
persons[i].name = malloc(strlen(item) + 1);
persons[i].len_name = strlen(item);
persons[i].id = i;
strcpy(persons[i].name, item);
item = strtok(NULL, ",");
}
for (unsigned int i = 0; i < num_persons; i++)
{
printf("%d: %s | %d\n", persons[i].id, persons[i].name, persons[i].len_name);
}
for (unsigned int i = 0; i < num_persons; i++)
{
free(persons[i].name);
}
}

Related

Getting a segmentation fault error on an Open Addressing Hash Map?

I'm getting a segmentation fault error somewhere in my insert function. It says that its due to one of the 'strcmp' comparisons but i cant find the issue after looking at all of them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define INITIAL_CAPACITY 8
typedef struct node
{
unsigned int val;
char *key;
bool del;
} Node;
typedef Node * NodePtr;
typedef struct hashMap
{
NodePtr array;
size_t capacity;
size_t size;
} HashMap;
typedef HashMap * HMPtr;
//|-------------------------
HMPtr create();
void insert(HMPtr map, char *str);
//y
void resize_insert(HMPtr map, char *str);
//y
void print(HMPtr map);
void destroy(HMPtr *mapPtr);
void resize(HMPtr map);
//y
unsigned int hash(char *str);
//y
unsigned int pop(HMPtr map, char *key);
//y
//|-------------------------
int main(void)
{
HMPtr map = create();
insert(map, "Keathan");
insert(map, "Trey");
insert(map, "Noah");
insert(map, "Kleiner");
insert(map, "data");
insert(map, "Matthew");
print(map);
destroy(&map);
return 0;
}
unsigned int pop(HMPtr map, char *str)
{
unsigned int val = hash(str);
size_t h = (size_t)val;
size_t index = h % map->capacity;
for(size_t i = 0; map->array[index].key && strcmp(str, map->array[index].key);index = (h + ((++i) + i*i)/2)%map->capacity);
if (map->array[index].key)
{
map->array[index].del = true;
return map->array[index].val;
}
return 0;
}
unsigned int hash(char *str)
{
unsigned int out = 0;
unsigned int base = 31;
unsigned int factor = 1;
for (size_t i = 0; str[i] != 0; ++i)
{
out += (unsigned int)str[i] * factor;
factor *= base;
}
return out;
}
void resize(HMPtr map)
{
NodePtr old = map->array;
size_t old_capacity = map->capacity;
map->capacity = old_capacity * 2;
map->array = calloc(map->capacity, sizeof(Node));
for(size_t i = 0; i < old_capacity; ++i)
{
if(old[i].key)
{
if(old[i].del)
free(old[i].key);
else
resize_insert(map, old[i].key);
}
}
free(old);
}
void resize_insert(HMPtr map, char *str)
{
unsigned int val = hash(str);
size_t h = (size_t)val;
size_t index = h % map->capacity;
for (size_t i = 0; map->array[index].key; index = (h + ((++i) + i*i)/2)%map->capacity);
map->array[index].key = str;
map->array[index].val = val;
++(map->size);
}
void insert(HMPtr map, char *str)
{
unsigned int val = hash(str);
size_t h = (size_t)val;
size_t index = h % map->capacity;
size_t i;
NodePtr deleted = NULL;
for(i = 0; map->array[index].key && strcmp(str, map->array[index].key);index = (h + ((++i) + i*i)/2)%map->capacity)
if(!deleted && map->array[index].del)
{
deleted = map->array + index;
for(index = (h + ((++i) + i*i)/2)%map->capacity; map->array[index].key && strcmp(str, map->array[index].key); index = (h + ((++i) + i*i)/2)%map->capacity);
break;
}
if (map->array[index].key == NULL)
{
if(deleted)
{
free(deleted->key);
deleted->del = false;
index = deleted - map->array;
}
else if (++(map->size) >= 0.7*map->capacity)
{
resize(map);
index = h % map->capacity;
for (i = 0; map->array[index].key; index = (h + ((++i) + i*i)/2)%map->capacity);
}
map->array[index].key = calloc(strlen(str)+1, sizeof(char));
strcpy(map->array[index].key, str);
}
else
map->array[index].val = val;
}
HMPtr create()
{
HMPtr newList = malloc(sizeof(HashMap));
newList->size = 0;
newList->capacity = INITIAL_CAPACITY;
newList->array = calloc(newList->capacity, sizeof(NodePtr));
return newList;
}
void destroy(HMPtr *mapPtr)
{
free((*mapPtr)->array);
free(*mapPtr);
*mapPtr = NULL;
}
void print(HMPtr map)
{
for (size_t i = 0; i < map->capacity; ++i)
printf("%s;%u\n", map->array[i].key, map->array[i].val);
}
This is the Error i recieved after running on gdb
'''
Program received signal SIGSEGV, Segmentation fault.
__strcmp_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S:30
30 ../sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S: No such file or
directory.
'''
If anyone could spot the issue then that would help a lot. Thanks!
sizeof(nodePtr) is size of pointer you need sizeof(struct Node)
HMPtr create()
{
HMPtr newList = malloc(sizeof(HashMap));
newList->size = 0;
newList->capacity = INITIAL_CAPACITY;
newList->array = calloc(newList->capacity, sizeof(*newList->array));
return newList;
}

Runtime error on Leetcode

When I submit my code to Leetcode, it reported runtime error as:
Line 43: member access within null pointer of type 'struct bucket_item'.
I tested that case in my local, it works fine. I thought it maybe causeed by the platform and compiler are different. I then tried to test it on Leetcode Playground. It also worked very well. The Leetcode problem is: https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/
Very appreciated if anyone could let me know what's wrong with my code.
typedef struct bucket_item {
char *str;
int count;
int ori_count;
} bucket_item;
typedef struct bucket {
int hashIndex;
int itemsCount;
bucket_item *items;
} bucket;
bucket *hash_init(const int bucket_count)
{
bucket *buckets = malloc(sizeof(bucket) * bucket_count);
for (int i = 0; i < bucket_count; ++i)
{
buckets[i].items = NULL;
buckets[i].itemsCount = 0;
}
return buckets;
}
int get_hash(char *str, const int bucket_count) {
const int str_len = strlen(str);
int base = 0;
int i = 0;
while (str[i] != '\0')
{
base += str[i];
i++;
}
return ((base >> 3) * 2654435761) % bucket_count;
}
bucket_item *hash_lookup(bucket *buckets, char *str, const int bucket_count)
{
const int hash_index = get_hash(str, bucket_count);
bucket *bucket = buckets + hash_index;
for (int i = 0; i < bucket->itemsCount; ++i)
{
if (strcmp(str, bucket->items[i].str) == 0) return bucket->items + i;
}
return NULL;
}
void hash_add(bucket *buckets, char *str, const int bucket_count)
{
bucket_item *item = hash_lookup(buckets, str, bucket_count);
if (item)
{
item->count++;
item->ori_count = item->count;
}
else {
const int hash_index = get_hash(str, bucket_count);
bucket *bucket = buckets + hash_index;
bucket->itemsCount++;
bucket->items = (bucket_item *)realloc(bucket->items, sizeof(bucket_item) * bucket->itemsCount);
bucket->items[bucket->itemsCount - 1].str = str;
bucket->items[bucket->itemsCount - 1].count = 1;
bucket->items[bucket->itemsCount - 1].ori_count = 1;
}
}
void hash_free(bucket *buckets, const int bucket_count)
{
for (int i = 0; i < bucket_count; ++i)
{
free(buckets[i].items);
buckets[i].items = NULL;
}
free(buckets);
buckets = NULL;
}
bool is_match(char* str, bucket *hashmap, int bucket_count, char **words, int word_len, int word_size)
{
bool found = true;
char *subStr = malloc(sizeof(char) * (word_len + 1));
subStr[word_len] = '\0';
for (int i = 0; i < word_size; ++i)
{
memcpy(subStr, str + i * word_len, word_len);
bucket_item *item = hash_lookup(hashmap, subStr, bucket_count);
if (item)
{
item->count--;
}
else
{
found = false;
}
}
free(subStr);
subStr = NULL;
for (int i = 0; i < word_size; ++i)
{
bucket_item *item = hash_lookup(hashmap, words[i], bucket_count);
if (item->count != 0) {
found = false;
}
}
for (int i = 0; i < word_size; ++i)
{
bucket_item *item = hash_lookup(hashmap, words[i], bucket_count);
item->count = item->ori_count;
}
return found;
}
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int* findSubstring(char* s, char** words, int wordsSize, int* returnSize) {
if (wordsSize == 0) return NULL;
const int word_len = strlen(words[0]);
// prepare hashmap
bucket *hashmap = hash_init(wordsSize);
for (int i = 0; i < wordsSize; ++i)
{
hash_add(hashmap, words[i], wordsSize);
}
// loop long string.
int *ret = malloc(sizeof(int) * 1000);
*returnSize = 0;
const int s_len = strlen(s);
const int sub_strlen = word_len * wordsSize;
for (int i = 0; i < s_len; ++i)
{
const bool found = is_match(s + i, hashmap, wordsSize, words, word_len, wordsSize);
if (found)
{
ret[*returnSize] = i;
(*returnSize)++;
}
}
hash_free(hashmap, wordsSize);
ret = (int*)realloc(ret, sizeof(int) * (*returnSize));
return ret;
}
The case that report error is below:
int main() {
char *str = "ababaab";
char **words[] = { "ab", "ba", "ba" };
int returnSize = 0;
int *result = findSubstring(str, words, 3, &returnSize);
return 0;
}
When you call the hash_lookup function, it could return NULL in some cases. So when you use item->count in the next line, you may access a NULL pointer.
You should ensure that item isn't NULL first, and than use item->count, like so:
for (int i = 0; i < word_size; ++i)
{
bucket_item *item = hash_lookup(hashmap, words[i], bucket_count);
if (item != NULL && item->count != 0) {
found = false;
}
}
for (int i = 0; i < word_size; ++i)
{
bucket_item *item = hash_lookup(hashmap, words[i], bucket_count);
if (item != NULL) {
item->count = item->ori_count;
}
}

reads txt from file, cut them into words, and display

#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static WORDS heap[10000];
int heapSize;
void InitHeap()
{
heapSize = 0;
heap[0].words = NULL;
heap[0].count = -1;
}
void InsertHeap(char* string)
{
heapSize++;
strcpy(heap[heapSize].words, string);
int now = heapSize;
while (heap[now / 2].words > string)
{
heap[now] = heap[now / 2];
now /= 2;
}
strcpy(heap[now].words, string);
}
int DeleteHeap()
{
char* minElement, lastElement;
int child, now;
strcpy(minElement, heap[1].words);
strcpy(lastElement, heap[heapSize--].words);
for (now = 1; now * 2 <= heapSize; now = child)
{
child = now * 2;
if (child != heapSize && heap[child + 1].words < heap[child].words)
{
child++;
}
if (lastElement > heap[child].words)
{
strcpy(heap[now].words, heap[child].words);
}
else
{
break;
}
}
strcpy(heap[now].words, lastElement);
return now;
}
typedef struct _WORDS {
char words[64];
int count;
}WORDS;
char* MakeToken(void)
{
int i, j;
static char delim[256];
memset(delim, 0x0, 256);
for (i = 1, j = 0; i < 256; i++)
{
if (!isalpha(i)) delim[j++] = i;
}
return delim;
}
int main() {
int i = 0, cur = 0;
FILE *pFile;
char readLine[1024], *ptr;
char *token = MakeToken();
InitHeap();
pFile = fopen("C:\\Users\\Home\\Desktop\\dataset.txt", "r");
if (pFile == NULL) {
printf("File open failed.\n");
return 0;
}
while (fgets(readLine, 1024, pFile) != NULL) {
ptr = strtok(readLine, token);
while (ptr != NULL) {
InsertHeap(ptr);
ptr = strtok(NULL, token);
}
}
for (i = 0; i < heapSize; i++)
{
cur = DeleteHeap();
printf("%s %d\n", heap[cur].words, heap[cur].count);
}
return 0;
}
Error Message : Run-Time error #3
I want to make program that reads txt from file, cut them into words, and display on console. I make it, but it doesnt work. how to fix it?
I think static WORDS heap<- this part
or
delete part is error.
or its path is failure.
I see following errors in your code:
heap[0].words = NULL;
words is an array, not a dynamyc allocated pointer, so you cannot assign to NULL (you get a compiler error! Seems to me that the WORDS.word variable declaration is uncorrect).
strcpy(minElement, heap[1].words);
strcpy(lastElement, heap[heapSize--].words);
minElement and lastElement are not initialized and not allocated, so the strcpy function will fail.
Here is a way to correct the code, I changed the minimum possible. The following collect the words, count the number of occurences and print the result in alphabetical order:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct _WORDS {
char words[64];
int count;
} WORDS;
static WORDS heap[10000];
int heapSize;
void InitHeap()
{
heapSize = 0;
}
void InsertHeap(char* string)
{
int num = 0;
// Search string in heap array. if found, increase count.
for(num = 0; num < heapSize; ++num)
{
if(strcmp(string, heap[num].words) == 0)
{
heap[num].count++;
return;
}
}
// If not found, add it to the array.
strcpy(heap[heapSize].words, string);
heap[heapSize].count = 1;
heapSize++;
}
char* MakeToken(void)
{
int i, j;
static char delim[256];
memset(delim, 0x0, 256);
for (i = 1, j = 0; i < 256; i++)
{
if (!isalpha(i)) delim[j++] = i;
}
return delim;
}
int compare(const void* v1, const void* v2)
{
return strcmp((const char*)v1, (const char*)v2);
}
int main()
{
int i = 0, cur = 0;
FILE *pFile;
char readLine[1024], *ptr;
char *token = MakeToken();
InitHeap();
pFile = fopen("C:\\Users\\Home\\Desktop\\dataset.txt", "r");
if(pFile == NULL)
{
printf("File open failed.\n");
return 0;
}
while (fgets(readLine, 1024, pFile) != NULL)
{
ptr = strtok(readLine, token);
while (ptr != NULL)
{
InsertHeap(ptr);
ptr = strtok(NULL, token);
}
}
// Order alphabetically the heap array.
qsort(heap, heapSize, sizeof(WORDS), compare);
for (i = 0; i < heapSize; i++)
{
printf("%s %d\n", heap[i].words, heap[i].count);
}
return 0;
}
I've fixed some errors in the code and it started to produce some results. Since I do not understand completely your task, I cannot progress further. The working code is as follows:
#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct _WORDS { char words[64]; int count; }WORDS;
static WORDS app_heap[10000];
int heapSize;
void InitHeap()
{
heapSize = 0;
app_heap[0].words[0] = '\0';
app_heap[0].count = -1;
}
void InsertHeap(char* string)
{
heapSize++;
strcpy(app_heap[heapSize].words, string);
int now = heapSize;
while (app_heap[now / 2].words > string)
{
app_heap[now] = app_heap[now / 2];
now /= 2;
}
strcpy(app_heap[now].words, string);
}
int DeleteHeap()
{
char minElement[64], lastElement[64];
int child, now;
if(heapSize <= 0)
{
printf("Wrong call\n");
return 0;
}
strcpy(minElement, app_heap[1].words);
strcpy(lastElement, app_heap[heapSize--].words);
for (now = 1; now * 2 <= heapSize; now = child)
{
child = now * 2;
if (child != heapSize && app_heap[child + 1].words < app_heap[child].words)
{
child++;
}
if (lastElement > app_heap[child].words)
{
strcpy(app_heap[now].words, app_heap[child].words);
}
else
{
break;
}
}
strcpy(app_heap[now].words, lastElement);
return now;
}
char* MakeToken(void)
{
int i, j;
static char delim[256];
memset(delim, 0x0, 256);
for (i = 1, j = 0; i < 256; i++)
{
if (!isalpha(i)) delim[j++] = i;
}
return delim;
}
int main() {
int i = 0, cur = 0;
FILE *pFile;
char readLine[1024], *ptr;
char *token = MakeToken();
InitHeap();
pFile = fopen("dataset.txt", "r");
if (pFile == NULL) {
printf("File open failed.\n");
return 0;
}
while (fgets(readLine, 1024, pFile) != NULL) {
ptr = strtok(readLine, token);
while (ptr != NULL) {
InsertHeap(ptr);
ptr = strtok(NULL, token);
}
}
for (i = 0; i < heapSize; i++)
{
cur = DeleteHeap();
printf("%s %d\n", app_heap[cur].words, app_heap[cur].count);
}
return 0;
}

C int pointer allocation size [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
its a very very anoing problem what i get. My problem is, gcc seems not allocate enough space to my int pointer.
Here is the code:
fns = (int*)calloc(c,sizeof(int));
So, after then i fill up this in a simple loop ones and zeros:
offset = seekToFirstParam(fnString,n);
i = 0;
while(i<c) {
tmp[i] = readNextParam(fnString,n,offset,&s);
if (isFunctionString(tmp[i])) {
fns[i] = 1;
} else {
fns[i] = 0;
}
i++;
}
So this is a "flag" array, but when i debug this, and print the elements i get:
156212102, 0, 0, 0, 1, 1
Or som. like this. I don't get it, because if in the calloc method i write 1000 like this:
fns = (int*)calloc(1000,sizeof(int));
After works fine.
Ok, this is a hole function:
char **readFnParams(char *fnString, int n, int *count, int **func) {
char **tmp;
int *fns = NULL;
int c,i = 0,offset,s;
c = getParamsCount(fnString,n);
if (!c) {
return NULL;
}
tmp = (char**)calloc(c,sizeof(char));
fns = (int*)calloc(c,sizeof(int*));
offset = seekToFirstParam(fnString,n);
while(i<c) {
tmp[i] = readNextParam(fnString,n,offset,&s);
if (isFunctionString(tmp[i])) {
tmp[i] = readNextFunctionParam(fnString,n,offset,&s);
offset = seekToNextParam(fnString,n,offset + s - 1);
fns[i] = 1;
} else {
fns[i] = 0;
offset = seekToNextParam(fnString,n,offset);
}
i++;
}
*func = fns;
*count = c;
return tmp;
}
:) Ok, this is a hole .c file. Yes my previous q. end this connected, becouse its a homework.
#ifndef exccel_builder_source
#define exccel_builder_source
#include "exccel_builder.h"
#include "exccel_utils.h"
#include "exccel_function.h"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
table* _processing;
//A végére fűzi az új elemeket
void addProcess(cell_process **LIST, cell_process *new) {
if (*LIST == NULL) {
new->next = NULL;
*LIST = new;
return;
}
new->next = *LIST;
*LIST = new;
}
void build(table* table) {
int col = table->matrix->col;
int row = table->matrix->row;
int i,j;
table_cell *cellTemp;
_processing = table;
for (i = 1; i<=row; i++) {
for (j = 1; j<=col; j++) {
cellTemp = getCell(table,i,j);
if (cellTemp != NULL) {
buildCell(cellTemp);
}
}
}
}
void buildCell(table_cell *cell) {
//Begins with '='
if (isFunction(cell)) {
buildCellWithFunction(cell);
}
}
void printProcesses(cell_process *LIST, int tab) {
cell_process *tmp = NULL;
int i = 0;
tmp = LIST;
while(tmp != NULL) {
i = 0;
while(i++<tab) printf(" ");
printf("%s, %d, paramPos: %i\n",tmp->func->name,tmp->func->paramsCount,tmp->paramPos);
if (tmp->childs != NULL) {
i = 0;
while(i++<tab + 3) printf(" ");
printf("Childs\n");
printProcesses(tmp->childs, tab + 3);
}
tmp = tmp->next;
}
}
void buildCellWithFunction(table_cell *cell) {
cell_process *HEAD = NULL;
buildCellProcessList(cell,&HEAD);
cell->cp = HEAD;
printf("%d,%d - cella:\n",cell->row,cell->col);
printProcesses(HEAD,0);
}
void buildCellProcessList(table_cell *cell, cell_process **HEAD) {
char *fnString;
int size;
fnString = getCellStringValue(cell, &size);
readFn(fnString,size,1,cell,HEAD,-1);
}
int readFn(char *fnString, int n, int offset, table_cell *cell, cell_process **LIST, int paramPos) {
char *fnName, *fnParam;
int fnNameLength;
int *fnSig;
int fnSigN;
int fnSigI;
int sig;
exccel_var *vtmp;
exccel_function *ftmp;
cell_process *ptmp;
char **parameters;
int *fnIndexes;
int paramsCount;
int paramI;
int i;
fnName = readFnName(fnString,n,offset,&fnNameLength);
ftmp = getExccelFunction(fnName);
if (ftmp == NULL) {
return 0;
}
ptmp = (cell_process*)malloc(sizeof(cell_process));
ptmp->cell = cell;
ptmp->func = ftmp;
ptmp->paramPos = paramPos;
ptmp->t = _processing;
ptmp->childs = NULL;
addProcess(LIST,ptmp);
parameters = readFnParams(fnString,n,&paramsCount,&fnIndexes);
allocParams(ptmp->func,paramsCount);
paramI = 0;
fnSig = ftmp->signature;
fnSigN = fnSig[0];
fnSigI = 1;
while(fnSigI <= fnSigN) {
sig = fnSig[fnSigI];
if (sig == FN_SIG_RANGE) {
fnParam = parameters[paramI];
vtmp = createExccelRangeVarFromString(fnParam);
//addParamToFunction(ftmp,vtmp);
addParamToFunctionAtPosition(ftmp,vtmp,paramI);
paramI++;
} else if (sig == FN_SIG_LITERAL) {
fnParam = parameters[paramI];
if (fnIndexes[paramI] == 1) {
readFn(fnParam,strlen(fnParam),0,cell,&((*LIST)->childs),paramI);
} else {
vtmp = createExccelVarFromString(fnParam);
//addParamToFunction(ftmp,vtmp);
addParamToFunctionAtPosition(ftmp,vtmp,paramI);
}
paramI++;
} else if (sig == FN_SIG_LIST) {
while(paramI<paramsCount) {
fnParam = parameters[paramI];
if (fnIndexes[paramI] == 1) {
readFn(fnParam,strlen(fnParam),0,cell,&((*LIST)->childs),paramI);
} else {
vtmp = createExccelVarFromString(fnParam);
//addParamToFunction(ftmp,vtmp);
addParamToFunctionAtPosition(ftmp,vtmp,paramI);
}
paramI++;
}
} else {
printf("Invalid signature %d\n",sig);
exit(1);
}
fnSigI++;
}
return 1;
}
char *readFnName(char *fnString, int n, int offset, int *size) {
char *fnName;
int nameBuffer, i, j;
i = offset;
j = 0;
nameBuffer = 8;
fnName = (char *)calloc(nameBuffer,sizeof(char));
while(*(fnString + i) != '(' && i<n) {
*(fnName + j++) = *(fnString + i++);
if (j>=nameBuffer) {
nameBuffer += 8;
fnName = (char *)realloc(fnName, nameBuffer);
}
}
*(fnName + j++) = '\0';
*size = j;
return fnName;
}
char **readFnParams(char *fnString, int n, int *count, int **func) {
char **tmp;
int *fns = NULL;
int c,i = 0,offset,s;
c = getParamsCount(fnString,n);
if (!c) {
return NULL;
}
tmp = (char**)calloc(c,sizeof(char));
fns = (int*)calloc(c,sizeof(*fns));
offset = seekToFirstParam(fnString,n);
while(i<c) {
tmp[i] = readNextParam(fnString,n,offset,&s);
if (isFunctionString(tmp[i])) {
tmp[i] = readNextFunctionParam(fnString,n,offset,&s);
offset = seekToNextParam(fnString,n,offset + s - 1);
fns[i] = 1;
} else {
fns[i] = 0;
offset = seekToNextParam(fnString,n,offset);
}
i++;
}
*func = fns;
*count = c;
return tmp;
}
int getParamsCount(char *fnString, int n) {
int i = 0, c = 0, jump = 0;
while(i<n) {
if (fnString[i] == '(') {
jump++;
} else if (fnString[i] == ',') {
if (jump == 1) c++;
} else if (fnString[i] == ')') {
jump--;
}
i++;
}
if (c > 0) {
return c + 1;
} else {
return 1;
}
}
int seekToFirstParam(char *fnString, int n) {
int i = 0;
while(fnString[i++] != '(' && i<n);
return i;
}
int seekToNextParam(char *fnString, int n, int offset) {
int i = offset;
while(fnString[i++] != ',' && i<n);
return i;
}
char *readNextParam(char *fnString, int n, int offset, int *size) {
char *params, c;
int paramBuffer, i, j;
i = offset;
j = 0;
paramBuffer = 8;
params = (char*)calloc(paramBuffer,sizeof(char));
while((c = fnString[i++]) != ',' && c != ')' && c != '(' && i<n) {
params[j++] = c;
if (j >= paramBuffer) {
paramBuffer += 8;
params = (char*)realloc(params,paramBuffer);
}
}
params[j] = '\0';
*size = j;
return params;
}
//Megfelelő számú nyitó ( - hez kell hogy legyen ugyanannyi )
char *readNextFunctionParam(char *fnString, int n, int offset, int *size) {
char *fn, c;
int fnBf, i, j, fnStarted = 0, fnClosed = 0;
i = offset;
j = 0;
fnBf = 8;
fn = (char*)calloc(fnBf, sizeof(char));
while((fnStarted != fnClosed || fnStarted == 0) && i<n) {
c = *(fnString + i++);
if (c == '(')
fnStarted++;
else if (c == ')')
fnClosed++;
*(fn + j++) = c;
if (j >= fnBf) {
fnBf += 8;
fn = (char*)realloc(fn, sizeof(char) * fnBf);
}
}
//*(fn + j++) = ')';
*(fn + j++) = '\0';
*size = j;
return fn;
}
#endif
And input like this:
=SZORZAT(MDETERM(A1:D4),NAGY(A1:D4,0),10,20,30)
It looks to me like you aren't allocating correctly, you have:
tmp = (char**)calloc(c,sizeof(char));
The first line, tmp, is allocating c elements of size char (c elements of 1 byte), I think you want c elements of size char * (c elements of size 4 or 8 bytes per element depending on if you are 32 or 64 bit platform). Since your routine readNextParam() is returning char * to store in this array, you need to change the calloc sizeof for tmp to:
tmp = calloc(c,sizeof(char*));
Because of this, I believe you have memory overwrites when you write into the tmp array that bleed into your other array. By making both "1000" elements, you've padded out that first calloc far enough that the overwrites are still in that same piece of memory.

storing CSV file to Float Matrix in C

Code does not store the value after the last comma of the line into matrix...
full list.csv is like:
123456,57,45,,67,,56,,63,,,72,67,,,,34,56,,,,,56,,,,,,,,,,,,,,45,,,,,1523521
123457,57,45,,67,,56,,634,,,72,67,,,,34,56,,,,,56,,,,,,,,,,,,,,45,,,1234,,
123458,57,45,,67,,56,,63,,,724,67,,,,34,56,,,,,56,,,,,,,,,,,,,,45,,,,1234,
123459,57,45,,67,,56,,63,,,72,647,,,,34,56,,,,,56,,,,,,,,,,,,,,45,,,,,1234
123450,57,45,,67,,56,,63,,,72,67,,,,344,56,,,,,56,,,,,,,,,,,,,,45,,,,,124
123451,57,45,,67,,56,,63,,,72,67,,,,34,564,,,,,56,,,,,,,,,,,,,,45,,,,,
123452,57,45,,67,,56,,63,,,72,67,,,,34,56,,,,,564,,,,,,,,,,,,,,45,,,,,124
123453,57,45,,67,,56,,63,,,72,67,,,,34,56,,,,,56,,,,,,,,,,,,,,454,,,,,
123454,57,45,,67,,56,,63,,,72,67,,,,34,56,,,,,56,,,,,,,,,,,,,,45,,,,,124
123455,574,45,,67,,56,,63,,,72,67,,,,34,56,,,,,56,,,,,,,,,,,,,,45,,,,,
123465,57,454,,67,,56,,63,,,72,67,,,,34,56,,,,,56,,,,,,,,,,,,,,45,,,,,
123466,57,45,,674,,56,,63,,,72,67,,,,34,56,,,,,56,,,,,,,,,,,,,,45,,,,,124
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int lines_allocated = 1000;
int max_line_len = 150;
double c[42][1000];
char **words = (char **)malloc(sizeof(char*)*lines_allocated);
if (words==NULL)
{
fprintf(stderr,"Out of memory (1).\n");
exit(1);
}
FILE *fp = fopen("full list.csv", "r");
if (fp == NULL)
{
fprintf(stderr,"Error opening file.\n");
exit(2);
}
int i;
for (i=0;1;i++)
{
int j;
if (i >= lines_allocated)
{
int new_size;
new_size = lines_allocated*2;
words = (char **)realloc(words,sizeof(char*)*new_size);
if (words==NULL)
{
fprintf(stderr,"Out of memory.\n");
exit(3);
}
lines_allocated = new_size;
}
words[i] = (char*)malloc(max_line_len);
if (words[i]==NULL)
{
fprintf(stderr,"Out of memory (3).\n");
exit(4);
}
if (fgets(words[i],max_line_len-1,fp)==NULL)
break;
for (j=strlen(words[i])-1;j>=0 && (words[i][j]=='\n' || words[i][j]=='\r');j--)
words[i][j]='\0';
}
int j;
int k=i;
for(j = 0; j < k; j++)
{
printf("%s\n", words[j]);
char *pptr = words[j];
int l;
for (l = 0; l < 42; l++)
{
char *ptr = strchr(pptr, ',');
if (ptr)
{
*ptr = 0;
c[l][j] = atof(pptr);
pptr = ptr + 1;
}
}
}
int l;
for (j = 0; j < k; j++)
{
printf("\n");
for (l = 0; l < 42; l++)
{
printf("%.2f\t", c[l][j]);
}
}
for (;i>=0;i--)
free(words[i]);
free(words);
return 0;
}
I think you miss a simple case: should be
#include <ctype.h>
...
char *ptr = strchr(pptr, ',');
if (ptr)
{
*ptr = 0;
c[l][j] = atof(pptr);
pptr = ptr + 1;
}
else if (isdigit(*pptr)) {
c[l][j] = atof(pptr);
}

Resources