Jetzt funktioniert es alles einwandfrei.
Ich hab die Postings von euch durchgearbeitet so gut es ging. Und den Code aufgeräumt.
Also, das Makefile zum Code verwendet nun
gcc und
-std=c99 zum kompilieren.
Damit bin ich erstmal die ganzen Compiler Fehler durchgegangen.
Danach die Tips von Brother John, wobei er Recht hatte das der Wert "tagCount" nicht initialisiert war und "irgendwas" hätte sein können, aber nicht 0. Gleich behoben.
Das letzte Element ist aber "tagCount" und nicht "tagCount -1" im Code - der Counter wird erst erhöht nachdem das Element angelegt ist.
Der Fehler mit dem 1 Zeichen für "currentTag" ist nun auch beboben so das "strlen(currentTag)+1" Zeichen allokiert werden (auch der Hinweis von exomo).
@exomo,
ich gehe an dieser Stelle nicht auf jeden Punkt ein, aber wie beschrieben ist die "strlen(string)+1" und das letzte Zeichen eines Char Arrays jetzt Nullterminiert, auch nach strcpy-Anweisungen (was echt umständlich ist...)
Globale Zählervariablen sind entfernt und werden nun direkt in den Schleifen (daher die Option -std=c99) initialisiert.
sourceFilePath und outputFilePath sind nun nicht mehr hardcoded, dies war aber lazyness von meiner Seite beim testen um die Parameterübergabe zu vermeiden, ist nun aber auch behoben. Also Parameter sind erforderlich.
Die Speicherallokierungen habe ich noch drin, aber es wäre jetzt wohl ein leichtes eine fixen Speicherbereich für jetzt Element mit calloc vorzureservieren.
Und last but not least, der aktuelle Stand - tut nicht viel, aber die gesamte Logik und Schaltungen müssen nochmal überarbeitetet werden damit XML Tags korrekt geparst werden können, Key-Values usw...
Also "non working" but "political correct"
Danke euch allen!
[src=c]/// Import c header files
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
// Enum and tructs
enum dataTypes {
ROOT = 0,
NUMBER = 1,
TEXT = 2,
ARRAY = 3
};
struct keyValue {
char* key;
char* value;
};
struct tag {
bool isDataTag;
unsigned int dataLength;
char* name;
char* tagData;
struct keyValue* data;
};
struct taglist {
unsigned int tagCount;
struct tag* tags;
};
// Function declarations
void cleanupApplication();
// Variables
char* sourceFilePath = NULL;
char* outputFilePath = NULL;
char* jsonData;
FILE* sourceFile;
FILE* outputFile;
struct taglist tagList;
// Main
int main(int argc, char* argv[]) {
char* arg = (char*) malloc(sizeof (char) * 3);
char* value = NULL;
atexit(cleanupApplication);
/* Comment me out for debugging*/
//sourceFilePath = (char*) calloc(11, sizeof (char));
//strcpy(sourceFilePath, "sample.xml");
//sourceFilePath[10] = '\0';
// Parse the commands given
for (int i = 1; i < argc; i++) {
if (strlen(argv
) > 2) {
strncpy(arg, argv, 2);
arg[3] = '\0';
argv += 2;
if (value == NULL) {
value = (char*) calloc(strlen(argv) + 1, sizeof (char));
} else {
value = (char*) realloc(value, sizeof (char) * (strlen(argv) + 1));
}
strcpy(value, argv);
value[ strlen(argv) ] = '\0';
switch (arg[1]) {
case 'i':
sourceFilePath = (char*) malloc(sizeof (char) * (strlen(value) + 1));
strcpy(sourceFilePath, value);
printf("Source: %s\n", value);
break;
case 'o':
outputFilePath = (char*) malloc(sizeof (char) * (strlen(value) + 1));
strcpy(outputFilePath, value);
printf("Output: %s\n", value);
default:
break;
}
}
}
if (arg != NULL) {
free(arg);
}
if (value != NULL) {
free(value);
}
// Reading the source file
if (sourceFilePath == NULL) {
printf("No input file specified...\n");
exit(0);
} else {
if (outputFilePath == NULL) {
outputFilePath = (char*) realloc(outputFilePath, sizeof (char)*(strlen("output.json") + 1));
strcpy(outputFilePath, "output.json");
outputFilePath[strlen("output.json")] = '\0';
}
unsigned int bufferLength = 0;
// Get and create a buffer for the source data
sourceFile = fopen(sourceFilePath, "r");
if (sourceFile == NULL) {
printf("Error opening input file.\n");
exit(1);
} else {
fseek(sourceFile, 0, SEEK_END);
bufferLength = ftell(sourceFile);
rewind(sourceFile);
char* srcData = (char*) calloc(bufferLength, sizeof (char));
char* tagData = (char*) calloc(1, sizeof (char));
char* tagKey = (char*) calloc(1, sizeof (char));
char* tagValue = (char*) calloc(1, sizeof (char));
char* currentTag = (char*) calloc(1, sizeof (char));
char* previousTag = (char*) calloc(1, sizeof (char));
tagData[0] = '\0';
tagKey[0] = '\0';
tagValue[0] = '\0';
currentTag[0] = '\0';
previousTag[0] = '\0';
bool hasOpenTag = false;
bool isInsideTag = false;
bool tagHasData = false;
bool insideKeyValue = false;
bool ignoreTag = false;
bool hasPreviousSpace = false;
bool specialCharAhead = false;
tagList.tagCount = 0;
tagList.tags = NULL;
tagList.tags = (struct tag*) malloc(sizeof (struct tag));
unsigned int tagWritePos = 0, dataWritePos = 0;
char data = '\0';
while (!feof(sourceFile)) {
data = fgetc(sourceFile);
switch (data) {
case '?':
if (hasOpenTag && tagWritePos == 0) {
hasOpenTag = false;
ignoreTag = true;
continue;
}
break;
case '\\':
specialCharAhead = true;
break;
case '\n':
case '\r':
continue;
break;
case '/':
if (hasOpenTag) {
continue;
}
case '<':
if (!specialCharAhead && !hasOpenTag) {
hasOpenTag = true;
isInsideTag = false;
tagWritePos = 0;
specialCharAhead = false;
continue;
}
break;
case '>':
if (ignoreTag) {
ignoreTag = false;
hasOpenTag = false;
tagWritePos = 0;
currentTag = (char*) realloc(currentTag, sizeof (char));
currentTag[0] = '\0';
tagData = (char*) realloc(tagData, sizeof (char));
tagData[0] = '\0';
dataWritePos = 0;
isInsideTag = true;
continue;
}
// React if we are insideKeyValuePair
if (insideKeyValue) {
printf("key: %s | value: %s\n", tagKey, tagValue);
insideKeyValue = false;
tagWritePos = 0;
tagValue = (char*) realloc(tagValue, sizeof (char));
tagValue[0] = '\0';
tagKey = (char*) realloc(tagKey, sizeof (char));
tagKey[0] = '\0';
}
tagHasData = false;
if (!specialCharAhead && hasOpenTag) {
if (strlen(tagData) > 1) {
if (tagList.tags[tagList.tagCount - 1].tagData == NULL) {
tagList.tags[tagList.tagCount - 1].isDataTag = true;
tagList.tags[tagList.tagCount - 1].tagData = (char*) calloc(strlen(tagData) + 1, sizeof (char));
strcpy(tagList.tags[tagList.tagCount - 1].tagData, tagData);
tagList.tags[tagList.tagCount - 1].tagData[strlen(tagData)] = '\0';
}
}
tagData = (char*) realloc(tagData, sizeof (char));
tagData[0] = '\0';
dataWritePos = 0;
if (strcmp(currentTag, previousTag) != 0) {
tagList.tags = (struct tag*) realloc(tagList.tags, sizeof (struct tag) * (tagList.tagCount + 1));
tagList.tags[tagList.tagCount].name = (char*) malloc(sizeof (char) * (strlen(currentTag) + 1));
strcpy(tagList.tags[tagList.tagCount].name, currentTag);
tagList.tags[tagList.tagCount].name[strlen(currentTag)] = '\0';
tagList.tagCount++;
}
previousTag = (char*) realloc(previousTag, sizeof (char) * (strlen(currentTag) + 1));
strcpy(previousTag, currentTag);
previousTag[strlen(currentTag)] = '\0';
hasOpenTag = false;
tagWritePos = 0;
currentTag = (char*) realloc(currentTag, sizeof (char));
currentTag[0] = '\0';
isInsideTag = true;
continue;
} else {
specialCharAhead = false;
}
break;
case ' ':
if (isInsideTag) {
if (!hasPreviousSpace) {
hasPreviousSpace = true;
} else {
continue;
}
}
if (ignoreTag) {
continue;
}
if (hasOpenTag && insideKeyValue) {
printf("key: %s | value: %s\n", tagKey, tagValue);
insideKeyValue = false;
tagWritePos = 0;
tagValue = (char*) realloc(tagValue, sizeof (char));
tagValue[0] = '\0';
tagKey = (char*) realloc(tagKey, sizeof (char));
tagKey[0] = '\0';
}
if (hasOpenTag) {
tagHasData = true;
tagWritePos = 0;
continue;
}
break;
case '=':
if (ignoreTag) {
continue;
}
if (tagHasData) {
insideKeyValue = true;
tagWritePos = 0;
continue;
}
break;
default:
hasPreviousSpace = false;
break;
}
if (hasOpenTag) {
if (!tagHasData) {
currentTag = (char*) realloc(currentTag, sizeof (char) * (tagWritePos + 2));
currentTag[tagWritePos] = data;
currentTag[tagWritePos + 1] = '\0';
++tagWritePos;
} else if (!insideKeyValue) {
tagKey = (char*) realloc(tagKey, sizeof (char) * (tagWritePos + 2));
tagKey[tagWritePos] = data;
tagKey[tagWritePos + 1] = '\0';
++tagWritePos;
} else {
tagValue = (char*) realloc(tagValue, sizeof (char) * (tagWritePos + 2));
tagValue[tagWritePos] = data;
tagValue[tagWritePos + 1] = '\0';
++tagWritePos;
}
} else {
tagData = (char*) realloc(tagData, sizeof (char) * (dataWritePos + 2));
tagData[dataWritePos] = data;
tagData[dataWritePos + 1] = '\0';
++dataWritePos;
}
}
for (int i = 0; i < tagList.tagCount; i++) {
printf("%s\n", tagList.tags.name);
if (tagList.tags.dataLength != 0) {
for (int j = 0; j < tagList.tags.dataLength; j++) {
printf("keyValue: %s = %s\n", tagList.tags.data[j].key, tagList.tags.data[j].value);
}
}
if (tagList.tags.isDataTag) {
printf("%s\n", tagList.tags.tagData);
printf("\n");
}
}
fclose(sourceFile);
free(srcData);
if (tagKey != NULL) {
free(tagKey);
}
if (tagValue != NULL) {
free(tagValue);
}
if (tagData != NULL) {
free(tagData);
}
if (currentTag != NULL) {
free(currentTag);
}
if (previousTag != NULL) {
free(previousTag);
}
}
}
return 0;
}
// Clean up by freeing ressources
void cleanupApplication() {
printf("\nFreeing ressources...\n");
for (int i = 0; i < tagList.tagCount; i++) {
if (tagList.tags.tagData != NULL) {
free(tagList.tags.tagData);
}
for (int j = 0; j < tagList.tags.dataLength; j++) {
free(tagList.tags.data[j].key);
free(tagList.tags.data[j].value);
}
free(tagList.tags.name);
}
if (jsonData != NULL) {
free(jsonData);
}
if (sourceFilePath != NULL) {
free(sourceFilePath);
}
if (outputFilePath != NULL) {
free(outputFilePath);
}
printf("Clean up done. Exiting. Bye bye...\n");
}
[/src]