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

#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;
}

Related

Only printing last line of txt file when reading into struct array in C

I am reading from a txt file into an array of structures. Example txt:
-4.5 -1 0 0
4.0 1 0 0
8 0 1 2
12.1 0 -6 1
-3.2 2.5 -3.0 4
The 4 values of each line correspond to the 4 values in the structure. The file may contain up to 100 lines (MAX is defined as 100). With the following code I am trying to store each line into the respective index of the struct array and then print:
FILE *fileName = NULL;
typedef struct chargeData_struct {
double Q, x, y, z;
} ChargeData;
ChargeData values[MAX], *p = values;
fileName = fopen("charge2.txt", "r");
if (fileName == NULL)
{
printf("ERROR: Could not open file.");
}
int k = 0;
while (fscanf(fileName, "%lf %lf %lf %lf", &p[k].Q, &p[k].x, &p[k].y, &p[k].z) != EOF);
{
printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
k++;
}
fclose(fileName);
However, only the last line of the txt file is printed. Is the same index of the struct array being overwritten each time?
You are using an extra semicolon which makes all the trouble, here:
while (fscanf(...) != EOF);
{
...
Remove it and you should be fine.
What happens with your code is that while(..); is equivalent to this:
while(...)
{
; // do nothing
}
thus does not enter the body (the one you think is the body) of your loop (since the actual body does nothing). However scanf() continues to parse the file, and then this section of your code executes:
{
printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
k++;
}
independently, where the curly braces are treated like they wanted to state scope.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define LINE_BUFFER_LEN (512)
#define RESERVE_NEWLINDE 0
#define AUTO_FILTER_NEWLINDE 1
typedef int (* LINE_READER)(char * pstrLine, int uiBufferLen, void * pvData);
typedef struct st_HW_SSP_CONFIG
{
const char * pstrConfigPath;
LINE_READER pfLineReader;
FILE * pstFile;
void * pvData;
int CurrentLine;
int Flag;
} CONFIG_ST;
int CloseConfig(CONFIG_ST * pstConfig)
{
if (!pstConfig)
{
// record error
return -1;
}
if (fclose(pstConfig->pstFile))
{
// record error
}
return 0;
}
int OpenConfigFile(const char * pstrFilePath, CONFIG_ST * pstConfig)
{
FILE * pstFile = NULL;
if ((!pstrFilePath) || (!pstConfig))
{
return -1;
}
pstFile = fopen(pstrFilePath, "r");
if (!pstFile)
{
return -1;
}
pstConfig->pstFile = pstFile;
pstConfig->pstrConfigPath = pstrFilePath;
pstConfig->Flag = RESERVE_NEWLINDE;
return 0;
}
int IsNullStr(const char *pcStr)
{
const char *pcTmp = pcStr;
while ('\0' != *pcTmp)
{
if (!isspace(*pcTmp))
{
return 0;
}
pcTmp++;
}
return 1;
}
int IsEffectiveLine(char acFileLineBuffer[LINE_BUFFER_LEN])
{
if (0 == strlen(&acFileLineBuffer[0]))
{
return 0;
}
if ('#' == acFileLineBuffer[0]) // strip as a comment line
{
return 0;
}
if (IsNullStr(&acFileLineBuffer[0]))
{
return 0;
}
return 1;
}
void FilterNewLine(char* pcLine, int MaxNumLen)
{
int uiLen = strlen(pcLine);
if (uiLen > 1)
{
if ('\n' == pcLine[uiLen - 1])
{
pcLine[uiLen - 1] = '\0';
if (uiLen > 2)
{
if ('\r' == pcLine[uiLen - 2])
{
pcLine[uiLen - 2] = '\0';
}
}
}
}
return;
}
int ReadConfigFile(CONFIG_ST * pstConfig)
{
char acFileLineBuffer[LINE_BUFFER_LEN] = {0};
char * pstrRead = NULL;
int Ret = 0;
if (!pstConfig)
{
return -1;
}
if ((!pstConfig->pstFile) || (!pstConfig->pfLineReader))
{
return -1;
}
rewind(pstConfig->pstFile);
pstConfig->CurrentLine = 0;
do
{
memset((void *)&acFileLineBuffer[0], 0, LINE_BUFFER_LEN);
pstrRead = fgets(&acFileLineBuffer[0], LINE_BUFFER_LEN - 1, pstConfig->pstFile);
if (pstrRead)
{
pstConfig->CurrentLine ++;
if (0 == IsEffectiveLine(acFileLineBuffer))
{
continue;
}
if (AUTO_FILTER_NEWLINDE == pstConfig->Flag)
{
FilterNewLine(acFileLineBuffer, LINE_BUFFER_LEN - 1);
}
if (pstConfig->pfLineReader)
{
Ret = pstConfig->pfLineReader(&acFileLineBuffer[0],
LINE_BUFFER_LEN,
pstConfig->pvData);
if (Ret)
{
break;
}
}
}
}
while (pstrRead);
return Ret;
}
int ReadConfigFileEx(const char * pFilePath,
LINE_READER pfReader,
void * pData, int Flag)
{
int Ret = 0;
CONFIG_ST stConfig = {0};
Ret = OpenConfigFile(pFilePath, &stConfig);
if (Ret)
{
return Ret;
}
stConfig.pfLineReader = pfReader;
stConfig.pvData = pData;
stConfig.Flag = Flag;
Ret = ReadConfigFile(&stConfig);
CloseConfig(&stConfig);
return Ret;
}
int StringSplit(char *pcStr, char cFlag,
char * pstArray[], int MaxNum,
int *pNum)
{
char * pcStrTemp = 0;
unsigned int uiIndex = 0;
pcStrTemp = pcStr;
while (pcStrTemp)
{
pstArray[uiIndex] = pcStrTemp;
pcStrTemp = strchr(pcStrTemp, cFlag);
if (pcStrTemp)
{
*pcStrTemp = '\0';
pcStrTemp ++;
uiIndex ++;
}
if (uiIndex >= MaxNum)
{
break;
}
}
if (0 != MaxNum)
{
*pNum = uiIndex >= MaxNum ? (MaxNum - 1) : uiIndex;
}
else
{
*pNum = 0;
}
return 0;
}
int MyLineReader(char * pstrLine, int uiBufferLen, void * pvData)
{
printf("Read line:[%s]\r\n", pstrLine);
char *pArray[8] = {0};
int Num = 0;
int index = 0;
StringSplit(pstrLine, ' ', pArray, 8, &Num);
for (index = 0; index <= Num; index ++)
{
printf("Get value :[%s]\r\n", pArray[index]);
}
return 0;
}
int main(int argc, char * argv[])
{
int ret = 0;
if (argc != 2)
{
printf("Please input file to read.\r\n");
return 0;
}
ret = ReadConfigFileEx(argv[1], MyLineReader, NULL, AUTO_FILTER_NEWLINDE);
if (ret)
{
printf("Open file error.\r\n");
}
return 0;
}

Segmentation fault using fgets in C

My code is not working and it is when I call fgets in the commandSplit function. I figured this out by printing "Am I here" in multiple places and find that the error at fgets it seems. I may be wrong, but I am pretty sure. I get a segmentation fault and I can not figure out why. Below is my code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAX_CHARACTERS 512
int Execute(char *a[], int t[], int num) {
int exitShell = 0;
int l = 0;
for (int i = 0; i < num; i++) {
int status;
if (strcmp(a[0], "quit") == 0) {
exitShell = 1;
}
if (t[i] && ((strcmp(a[l], "quit") == 0))) {
exitShell = 1;
}
char *holder[t[i]+1];
for (int j = 0; j < t[i]; j++) {
holder[j] = a[l];
l++;
}
holder[t[i]] = NULL;
pid_t p = fork();
pid_t waiting;
if (p == 0) {
execvp(holder[0], holder);
fprintf(stderr, "Child process could not execvp!\n");
exit(1);
} else {
if (p < 0) {
fprintf(stderr, "Fork FAILED!\n");
} else {
waiting = wait(&status);
printf("Child %d exit with status %d\n", waiting, status);
}
}
for (int g = 0; g < t[i]; g++) {
a[g] = NULL;
}
}
for (int i = 0; i < num; i++) {
t[i] = 0;
}
return exitShell;
}
int commandSplit(char *c, FILE *f, char *a[], int t[]) {
int count = 0;
int emptyfile = 1;
int stat = 0;
int total1 = 0;
char *temp[MAX_CHARACTERS];
if (c != NULL) {
char *readCommands = strtok(c, ";");
while (readCommands != NULL) {
temp[count] = readCommands;
count++;
readCommands = strtok(NULL, ";");
}
for (int i = 0; i < count; i++) {
char *read = strtok(temp[i], " ");
int track1 = 0;
while (read != NULL) {
a[total1] = read;
track1++;
total1++;
read = strtok(NULL, " ");
}
t[i] = track1;
}
stat = Execute(a, t, count);
} else {
char *buildCommands = "";
printf("Am I here???\n");
while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
printf("Am I here???\n");
emptyfile = 0;
commandSplit(buildCommands, NULL, a, t);
stat = Execute(a, t, count);
}
if (emptyfile) {
printf("File is empty!\n");
stat = 1;
}
}
printf("Am I here???\n");
return stat;
}
int main(int argc, char *argv[]) {
int exitProgram = 0;
FILE *fileRead = NULL;
if (argc == 2) {
fileRead = fopen(argv[1], "r");
if (fileRead == NULL) {
printf("No such file exists\n");
exitProgram = 1;
}
}
if (argc > 2) {
printf("Incorrect batch mode call\n");
exitProgram = 1;
}
char *args[MAX_CHARACTERS];
int tracker[MAX_CHARACTERS];
while (!exitProgram) {
if (argc == 1) {
char *commands = (char *)(malloc(MAX_CHARACTERS * sizeof(char)));
printf("tinyshell>");
if (fgets(commands, MAX_CHARACTERS, stdin) == NULL) {
exitProgram = 1;
printf("\n");
}
int len;
len = strlen(commands);
if (len > 0 && commands[len-1] == '\n') {
commands[len-1] = '\0';
}
if (len > MAX_CHARACTERS) {
printf("TOO MANY CHARACTERS - MAX: 512\n");
continue;
}
if (strlen(commands) == 0)
continue;
exitProgram = commandSplit(commands, NULL, args, tracker);
} else {
exitProgram = commandSplit(NULL, fileRead, args, tracker);
}
}
fclose(fileRead);
return 0;
}
As commented #Jean-François Fabre , buildCommands points to insufficient space and potential const space;
char *buildCommands = "";
...
// bad code
while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
Allocate space with an array or malloc()
char buildCommands[MAX_CHARACTERS];
...
while ((fgets(buildCommands, sizeof buildCommands, f) != NULL) && !stat) {
...
}
// or
char *buildCommands = malloc(MAX_CHARACTERS);
assert(buildCommands);
...
while ((fgets(buildCommands, MAX_CHARACTERS, f) != NULL) && !stat) {
...
}
...
free(buildCommands);

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);
}

Pointer to FILE nulling itself without being used at all

in the following code when ran will produce a Segmentation Fault, due to a FILE* being passed to fclose which contains no address (NULL).
I'm wondering why this is happening, the FILE* isn't being used what so over.
The FILE* is named urandom and is passed to fclose in the main function.
Thanks
#include <stdio.h>
#include <stdlib.h>
struct property
{
char *name;
unsigned int value;
unsigned int owner;
unsigned int type;
};
struct player
{
unsigned int id;
unsigned int money;
unsigned int position;
};
int rollDice(FILE *);
int amountOfLines(FILE *);
int createArrayOfPtrs(int ,void ***);
int makeArryOfPropertyPtrs(int ,struct property **);
int FillArryPropertyData(struct property **,int ,FILE *);
int splitBuffer(char *,unsigned int *,char **);
int bufferPropertyFile(FILE *,char **,int );
i nt fillPropertyStruct(struct property *,unsigned int ,char *);
int main(void)
{
int linesInPropertyFile = 0;
struct property **arrayForProperties = 0;
//Open /dev/urandom for rollDice
FILE *urandom = fopen("/dev/urandom","rb");
FILE *propertyFile = fopen("/home/jordan/Documents/Programming/Monopoly Project/properties","rb");
if(propertyFile == NULL || urandom == NULL)
{
puts("ERROR: error in opening file(s)");
return 1;
}
linesInPropertyFile = amountOfLines(propertyFile);
//DEBUG
printf("%d is contained within \"linesInPropertyFile\"\n",linesInPropertyFile);
if(createArrayOfPtrs(linesInPropertyFile,(void ***)&arrayForProperties))
{
puts("ERROR: error from createArrayOfPointers()");
return 1;
}
//DEBUG
printf("Outside Pointer: %p\n",arrayForProperties);
if(makeArryOfPropertyPtrs(linesInPropertyFile,arrayForProperties))
{
puts("ERROR: error from createArrayOfPointersForProperties()");
return 1;
}
if(FillArryPropertyData(arrayForProperties,linesInPropertyFile,propertyFile))
{
puts("ERROR: error from FillArryPropertyData()");
}
//Close FILE stream for /dev/urandom
fclose(urandom);
fclose(propertyFile);
return 0;
}
int FillArryPropertyData(struct property **array,int amntOfProperties,FILE *fp)
{
int bufferUsed = 100;
int i = 0;
int returnValue = 0;
int returnValue2 = 0;
unsigned int money = 0;
char *name;
char *buffer;
rewind(fp);
while(returnValue == 0)
{
buffer = malloc(bufferUsed);
returnValue = bufferPropertyFile(fp,&buffer,bufferUsed);
if(returnValue && returnValue != -1)
{
puts("ERROR: error from bufferPropertyFile()");
return -1;
}
if(returnValue == -1)
{
break;
}
if(buffer[0] != '\0')
{
returnValue2 = splitBuffer(buffer,&money,&name);
}
if(returnValue2)
{
puts("ERROR: error in splitBuffer()");
return 1;
}
if(fillPropertyStruct(array[i],money,name))
{
puts("ERROR: error in fillPropertyStruct()");
return 1;
}
money = 0;
i++;
}
free(buffer);
return 0;
}
int fillPropertyStruct(struct property *array,unsigned int money,char *name)
{
int nameSize = 100;
int i = 0;
array->name = malloc(nameSize);
array->value = money;
while(1)
{
if(i >= nameSize)
{
void *tmp = realloc(array->name,nameSize * 2);
nameSize *= 2;
if(tmp)
{
array->name = tmp;
}
else
{
return -1;
}
}
if(name[i] == '\0')
{
break;
}
array->name[i] = name[i];
i++;
}
array->name[i] = '\0';
return 0;
}
int splitBuffer(char *buffer,unsigned int *money,char **name)
{
int i = 0;
int j = 1;
int nameSize = 100;
*name = malloc(nameSize);
while(1)
{
if(buffer[j] != '"')
{
(*name)[j-1] = buffer[j];
}
else
{
i++;
}
j++;
if(i)
{
break;
}
if(j >= nameSize)
{
void *tmp = 0;
tmp = realloc(*name,nameSize * 2);
nameSize = nameSize * 2;
if(tmp != NULL)
{
*name = tmp;
}
else
{
puts("ERROR: error in splitBuffer");
return -1;
}
}
}
name[j-1] = '\0';
while(buffer[j] != '$')
{
if(buffer[j] == '\0')
{
puts("ERROR: error in splitBuffer()");
return -2;
}
j++;
}
j++;
while(buffer[j] != '\0')
{
*money += (buffer[j] - '0');
if(buffer[j+1] != '\0')
{
*money *= 10;
}
j++;
}
printf("BUFFER: %s\n",buffer);
printf("NAME: %s\n",*name);
printf("MONEY: %d\n",*money);
return 0;
}
int bufferPropertyFile(FILE *fp,char **buffer,int i)
{
int j = (i - i);
if(feof(fp))
{
//-1 Returned if EOF detected
return -1;
}
char retr = 0;
while(1)
{
if(j + 1 >= i)
{
void *tmp = realloc(*buffer,i * 2);
if(tmp != NULL)
{
*buffer = tmp;
i = i * 2;
}
else
{
puts("ERROR: error in bufferPropertyFile()");
return -2;
}
}
retr = fgetc(fp);
if(retr == '\n' || feof(fp))
{
break;
}
(*buffer)[j] = retr;
j++;
}
(*buffer)[j] = '\0';
if(**buffer == '\0')
{
return -1;
}
return 0;
}
int rollDice(FILE *fp)
{
int seed = fgetc(fp);
srand(seed);
return (rand() % 6) + 1;
}
int amountOfLines(FILE *file)
{
int i = 0;
int retr = 0;
while(1)
{
retr = fgetc(file);
if(retr == EOF)
{
break;
}
if(retr == '\n' )
{
i++;
}
}
return i;
}
int createArrayOfPtrs(int numberOfPointers,void ***pointer)
{
void *tmp = malloc(numberOfPointers * sizeof (tmp));
if(tmp != NULL)
{
*pointer = tmp;
//DEBUG
printf("Pointer: %p\n",*pointer);
}
else
{
return 1;
}
return 0;
}
int makeArryOfPropertyPtrs(int numberOfPointers,struct property **pointer)
{
int i = 0;
void *tmp;
for(i = 0;i < numberOfPointers;i++)
{
tmp = malloc(sizeof(struct property));
if(tmp == NULL)
{
return 1;
}
pointer[i] = (struct property *)tmp;
}
return 0;
}
here it givest an access violation in splitBuffer on this line:
name[j-1]='\0';
which probably should be
(*name)[j-1]='\0';
indeed that memory is not allocated anywhere, in other words, undefined behaviour, which indeed in your case might overwrite the urandom variable: both urandom and name are allocated on stack so depending on value of j it might write over urandom..
apart from that, there might be more errors, the number and use of pointers/mallocs/reallocs and lack of frees is a bit scary
int createArrayOfPtrs(int ,void ***);
if(createArrayOfPtrs(linesInPropertyFile,(void ***)&arrayForProperties))
This is undefined behaviour, a (void***) is not compatible to a (struct property ***). Why do you even use it here, all the other functions use struct property pointers?
Since the array is located right before the file pointer in the local variables of main, maybe the problem is that the array creation/initialization overwrites urandom?

Resources