In our student class we are building a small program to process the data from Oil & Gas Industry. The program at a rough condition, but we learn a lot through the project.
The program is compiled this way
In the below sections you can find the whole code of the source files. Here is the compilation routine:
gcc -fPIC -c parser.c -o parser.o
gcc -shared parser.c -o parser.dll
gcc -c well.c - o well.o
gcc -c main.c -o main.o
gcc main.o well.o -L. -lparser -o well.exe
Then we execute it this way: well.exe "WELL_DATA.csv" "NUM OF WELL TO FIND" >> well.log
The problem the execution starts, but the output from fprintf appears just sometimes, but usually not... We hope you can help us resolve our problem
main.c file content
#include"well.h"
FILE* input;
struct WELL* head = NULL; //the head of the list
struct TNode* tree = NULL;
int main(int argc, char *argv[3]) {
CBUFFER* buffer = malloc(sizeof(CBUFFER));
buffer->len = BUFFER_SIZE;
input = fopen(argv[1], "r");
struct WELL* instance = NULL;
while(buffer->len != 0){
flushBuffer(buffer);
getNextLine(input, buffer);
if (buffer->len == 0)
break;
parseData(buffer);
instance = createWell(buffer);
addWell(instance, &head);
}
instance = getWell(argv[2], head);
if (instance != NULL)
fprintf(stdout,"NAME = %s\tLIFT_TYPE = %i\tMONTHLY_OIL_FLOW_RATE = %.2f\n", instance->name, instance->prodMethod, instance->oil.monthly);
else fprintf(stdout,"No such well\n");
freeList(head);
fclose(input);
return 0;
}
In the following sections you can find the rest of the code. Here is the parser.c which processes the data:
#include "parser.h"
unsigned short getNextLine(FILE* input, CBUFFER* buffer){
//printf("Getting next line\n");
unsigned short len = 0;
char symbol = fgetc(input);
if (!input || !buffer)
return 0;
while ((symbol != '\n' && (symbol != EOF))){
//
*((buffer->data) + len) = symbol;
symbol = fgetc(input);
len++;
}
*((buffer->data) + len) = '\n';
buffer->len = len;
buffer->index = 0;
return buffer->len;
}
unsigned short parseData(CBUFFER* buffer){
char *temp = malloc(sizeof(char) * (buffer->len + 1));
unsigned short i = 0;
unsigned short j = 0;
while (*((buffer->data) + i) != '\n'){
if (*((buffer->data) + i) == '\0' || *((buffer->data) + i) == '\r' || *((buffer->data) + i) == '\v' ||
*((buffer->data) + i) == '\t' || *((buffer->data) + i) == '\f')
i++;
else{
if (*((buffer->data) + i) == ';')
*(temp + j) = '\0';
else
*(temp + j) = *((buffer->data) + i);
j++;
}
i++;
}
*(temp + j) = '\n';
flushBuffer(buffer);
i = 0;
while (*(temp + i) != '\n'){
*((buffer->data) + i) = *(temp + i);
i++;
}
*((buffer->data) + i) = '\0';
free(temp);
buffer->len = i;
return buffer->len;
}
char* getValue(CBUFFER* buffer)
{
int i = buffer->index;
int j = buffer->index;
char c;
for (; i <= buffer->len; i++)
{
c = buffer->data[i];
if (c == '\0')
{
char* newValue = (char*)malloc(sizeof(char) * (i - buffer->index + 1));
for (; j <= i ; j++)
{
newValue[j - buffer->index] = buffer->data[j];
}
newValue[j - buffer->index] = '\0';
buffer->index = i + 1;
return newValue;
}
}
return NULL;
}
DATE getDate(char* input, char delimeter){
DATE date;
unsigned short number = 0;
char c = input[0];
for(unsigned short i = 1, j = 0; i < 12; i++){
number = number * 10 + atoi(&c);
c = input[i];
if((c == delimeter) || (c == '\0')){
if (j == 0) date.day = number;
if (j == 1) date.month = number;
if (j == 2){
date.year = number;
break;
}
number = 0;
j++;
}
}
return date;
}
int flushBuffer(CBUFFER* buffer) {
unsigned short i = 0;
while( i < buffer->len){
*((buffer->data)+i) = '\0';
i++;
}
buffer->len = 0;
return 0;
}
And the part which defines the well-object we work with well.c:
#include "well.h"
struct WELL* createWell(CBUFFER* pbuffer) {
struct WELL* instance = malloc(sizeof(struct WELL));
char * nextValue = getValue(pbuffer);
unsigned i = 0;
while ( nextValue != NULL){
setProperty(instance, i, nextValue);
i++;
nextValue = getValue(pbuffer);
}
instance->next = NULL;
return instance;
}
unsigned setProperty(struct WELL* instance, unsigned prop_index, char* value) {
switch(prop_index){
case 0:
setWellName(instance, value);
break;
case 1:
setWellDate(instance, getDate(value, '/'));
break;
case 2:
setProductionMethod(instance, value);
break;
case 3:
setFormation(instance, value);
break;
case 4:
setPump(instance, value);
break;
case 5:
setProduction(instance, OIL, MONTH, atof(value));
break;
case 6:
setProduction(instance, OIL, YEAR, atof(value));
break;
case 7:
setProduction(instance, OIL, COMMULATIVE, atof(value));
break;
case 8:
setProduction(instance, WATER, MONTH, atof(value));
break;
case 9:
setProduction(instance, WATER, YEAR, atof(value));
break;
case 10:
setProduction(instance, WATER, COMMULATIVE, atof(value));
break;
// PAY ATTENTION THAT cases from 11 to 13 are skipped!
// THIS IS BECAUSE WE DON'T NEED m3 PARAMETERS as it is
// AND CAN CALCULATE THEM from tons using density parameter
case 14:
setProduction(instance, MIX, MONTH, atof(value));
break;
case 15:
setProduction(instance, MIX, YEAR, atof(value));
break;
case 16:
setProduction(instance, MIX, COMMULATIVE, atof(value));
break;
case 17:
setProduction(instance, MIX, MONTH, atof(value));
break;
case 18:
setProduction(instance, MIX, YEAR, atof(value));
break;
case 19:
setProduction(instance, MIX, COMMULATIVE, atof(value));
break;
}
return 0;
}
unsigned addWell(struct WELL* instance, struct WELL** head) {
if (*head == NULL) {
*head = instance;
} else {
struct WELL* tmp = *head;
while (tmp->next){
tmp = tmp->next;
}
tmp->next = instance;
}
return 0;
}
struct WELL* getWell(char* key, struct WELL* head) {
if (head == NULL) return NULL;
struct WELL* currentWell = head;
while (strcmp(currentWell->name, key) != 0) {
if (currentWell->next == NULL) return NULL;
currentWell = currentWell->next;
}
return currentWell;
}
char* setWellName(struct WELL* instance, char* value) {
strcpy(instance->name, value);
return instance->name;
}
char* setFormation(struct WELL* instance, char* value) {
strcpy(instance->devFormation, value);
return instance->devFormation;
}
char* setPump(struct WELL* instance, char* value) {
strcpy(instance->pump, value);
return instance->pump;
}
DATE setWellDate(struct WELL* instance, DATE date) {
instance->startDate.day = date.day;
instance->startDate.month = date.month;
instance->startDate.year = date.year;
return instance->startDate;
}
WLIFT_TYPE setProductionMethod(struct WELL* instance, char* value) {
if (!strcmp(value, "flush"))
instance->prodMethod = FLUSH;
if (!strcmp(value, "gaslift"))
instance->prodMethod = GAS_LIFT;
if (!strcmp(value, "pump"))
instance->prodMethod = PUMP;
return instance->prodMethod;
}
double setProduction(struct WELL* instance, WFLUID fluid, WPERIOD period , double value) {
if (fluid == OIL) {
if (period == MONTH) {
instance->oil.monthly = value;
return instance->oil.monthly;
} else if (period == YEAR) {
instance->oil.year = value;
return instance->oil.year;
} else if (period == COMMULATIVE) {
instance->oil.commulative = value;
return instance->oil.commulative;
}
} else if (fluid == GAS) {
if (period == MONTH) {
instance->gas.monthly = value;
return instance->gas.monthly;
} else if (period == YEAR) {
instance->gas.year = value;
return instance->gas.year;
} else if (period == COMMULATIVE) {
instance->gas.commulative = value;
return instance->gas.commulative;
}
} else if (fluid == WATER) {
if (period == MONTH) {
instance->water.monthly = value;
return instance->water.monthly;
} else if (period == YEAR) {
instance->water.year = value;
return instance->water.year;
} else if (period == COMMULATIVE) {
instance->water.commulative = value;
return instance->water.commulative;
}
} else if (fluid == MIX) {
if (period == MONTH) {
instance->liquid.monthly = value;
return instance->liquid.monthly;
} else if (period == YEAR) {
instance->liquid.year = value;
return instance->liquid.year;
} else if (period == COMMULATIVE) {
instance->liquid.commulative = value;
return instance->liquid.commulative;
}
}
}
Related
I have a small program to handle a list of rabbits (name, district, participation count) stored in an array of pointers (Rabbit** iterator). I'd like to implement the following methods: add, delete and modify a rabbit, list all the rabbits or list by district.
When I compare for example the name of the rabbits in the list with strcmp() it doesn't return 0 when the names are equal. How can I solve this problem?
The Rabbit struct:
typedef struct Rabbit {
char* name;
char* district;
unsigned part_count;
} Rabbit;
The delete method:
bool delete_rabbit(char* delete_name)
{
for (unsigned i = 0; i < size; ++i) {
if (iterator[i] != NULL && strcmp(iterator[i]->name, delete_name) == 0) {
free(iterator[i]);
iterator[i] = NULL;
count--;
return true;
}
}
return false;
}
The list by district method:
void list_by_district(char* district)
{
unsigned counter = 0;
for (unsigned i = 0; i < size; ++i) {
if (iterator[i] != NULL && strcmp(iterator[i]->district, district) == 0) {
counter++;
printf("\n%u. Rabbit:\n", counter);
printf("Name: %s\nDistrict: %s\nParticipation count: %u\n", iterator[i]->name, iterator[i]->district, iterator[i]->part_count);
}
}
}
The modify method is similar to the delete method except it only changes the values.
The corresponding code snippets from main:
Rabbit** iterator;
unsigned size = 10, count = 0;
int main()
{
iterator = (Rabbit**)malloc(sizeof(Rabbit*) * 10);
...
do {
...
switch (input) {
case 'a':
if (count == size) iterator = allocate_more_memory();
...
iterator[count++] = add_rabbit(new_name, new_district, new_part_count);
break;
case 'd':
if (size == count + 6) iterator = allocate_less_memory();
do {
printf("Enter name to be deleted: ");
scanf("%[^\n]", delete_name);
getchar();
if (strlen(delete_name) >= 30) printf("Name only has 30 or less characters!\n");
} while (strlen(delete_name) >= 30);
if (!delete_rabbit(delete_name)) printf("\nThere's no rabbit in the list with this name.\n");
break;
...
}
} while (input != 'x');
...
free(iterator);
return 0;
}
EDIT:
The add method:
Rabbit* add_rabbit(char* new_name, char* new_district, unsigned new_part_count)
{
Rabbit* new_rabbit = (Rabbit*)malloc(sizeof(Rabbit));
if (new_rabbit) {
new_rabbit->name = (char*)malloc((strlen(new_name) + 1) * sizeof(char));
new_rabbit->district = (char*)malloc((strlen(new_district) + 1) * sizeof(char));
strcpy(new_rabbit->name, new_name);
strcpy(new_rabbit->district, district);
new_rabbit->part_count = new_part_count;
}
return new_rabbit;
}
The allocate less memory method:
Rabbit** allocate_less_memory()
{
Rabbit** new_iterator = (Rabbit**)malloc(sizeof(Rabbit*) * (size - 5));
if (new_iterator) {
unsigned counter = 0;
for (unsigned i = 0; i < size; ++i) {
if (iterator[i] != NULL) {
new_iterator[counter++] = iterator[i];
}
}
size -= 5;
free(iterator);
return new_iterator;
}
return NULL;
}
I need to program a small airport management system for a school project and I have a terrible bug in my code.
As soon as I initialize the airportManager with more than one airport, all the IATA codes in the airports array get the name of the last airport that was input.
I have tried debugging it a lot of time but without any success. Everything is fine until I print the IATA code or use it. I will be glad for any help.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define TEMP_STR_LEN 255
#define IATA_SIZE 3
// Airport struct:
struct Airport
{
char name[TEMP_STR_LEN];
char country[TEMP_STR_LEN];
char iata[IATA_SIZE];
} typedef airport;
// Airport functions:
int compareAirports(airport const *airport1, airport const *airport2)
{
if (strcmp(airport1->iata, airport2->iata) != 0)
return 0;
else
return 1;
}
int compareIataCode(airport *airport1, char const *iata)
{
if (strcmp(airport1->iata, iata) != 0)
return 0;
else
return 1;
}
void NameArrange(char *name)
{
char tmpString[255];
tmpString[0] = '\0';
char *token = strtok(name, " ");
int i, place = 0, strTotalLen = 0, lastTokenLen = 0;
while (token != NULL)
{
place++;
if (strlen(token) % 2 == 0)
{
for (i = 0; i < strlen(token) - 1; i++)
{
if (token[i] >= 'a' && token[i] <= 'z')
{
token[i] -= 32; // by ascii table
}
if ((token[i + 1] >= 'A' && token[i + 1] <= 'Z'))
token[i + 1] += 32; // by ascii table
i++;
}
}
else if (token[0] >= 'a' && token[0] <= 'z')
token[0] -= 32;
if (place != 1)
strcat(tmpString, " ");
strncat(tmpString, token, strlen(token));
strTotalLen += strlen(token);
lastTokenLen = strlen(token);
token = strtok(NULL, " ");
}
strTotalLen += (place - 1) * 2;
if (lastTokenLen % 2 != 0)
tmpString[strTotalLen - lastTokenLen] += 32;
strcpy(name, tmpString);
}
// ***Airport manager struct***
struct AirportManager
{
int airportsCount;
airport *airportArr;
} typedef airportMan;
// airportManager functions
void addAirport(airportMan *airportManager, airport *airportToAdd)
{
airportManager->airportArr = (airport *) realloc(airportManager->airportArr, (airportManager->airportsCount + 1) * (sizeof(airport)));
strcpy(airportManager->airportArr[airportManager->airportsCount].name, airportToAdd->name);
strcpy(airportManager->airportArr[airportManager->airportsCount].country, airportToAdd->country);
strcpy(airportManager->airportArr[airportManager->airportsCount].iata, airportToAdd->iata);
airportManager->airportsCount++;
printf(" BUG!!! %s\n", airportManager->airportArr[0].iata);
}
bool airportFind(airportMan *airportManager, char *iataCode)
{
int i;
printf("%s", airportManager->airportArr[0].iata );
char airportIata[IATA_SIZE];
char airportIata2[IATA_SIZE];
strcpy(airportIata, iataCode);
strcpy(airportIata2, airportManager->airportArr[0].iata);
if (strcmp(airportIata, airportIata2) == 0)
return true;
// for (i = 1; i < airportManager->airportsCount; i++) {
// printf("%s",airportManager->airportArr[0].iata );
// return true;
// }
puts("Airport not found");
return false;
}
bool checkDuplicatedIata(const airportMan *airportManger, const char *iata)
{
// checks if there is already airport with the same iata code as the input
int i;
for (i = 0; i < airportManger->airportsCount; i++)
{
if (compareIataCode(&(airportManger->airportArr[i]), iata))
{
puts("This IATA code is already exists, please try again");
return true;
}
}
return false;
}
bool checkIataSize(const char *iata)
{
if (strlen(iata) != IATA_SIZE)
{
puts("The IATA code must be 3 letters");
return false;
}
return true;
}
bool checkIataLetters(const char *iata)
{
// checks if all the letters in a given iata code are all capital
int i;
for (i = 0; i < strlen(iata); i++)
{
if (iata[i] >= 'a' && iata[i] <= 'z')
{
puts("The IATA code must be in capital letters");
return false;
}
}
return true;
}
bool checkIataOk(const char *iata, const airportMan *airportManager)
{
if (checkDuplicatedIata(airportManager, iata) == false
&& checkIataSize(iata) && checkIataLetters(iata))
return true;
else
return false;
}
airport *initAirport(airportMan *airportManager)
{
// asks the user to input an airport
airport *iniAirport;
iniAirport = (airport *) malloc(sizeof(airport));
char tmpStr[TEMP_STR_LEN];
char *ptr;
bool iataOk = false;
printf("please enter airport details (press enter to confirm):\nName:");
fflush(stdin);
fgets(tmpStr, 255, stdin);
if ((ptr = strchr(tmpStr, '\n')) != NULL)
*ptr = '\0';
strcpy(iniAirport->name, tmpStr);
NameArrange(iniAirport->name);
printf("Country:");
fgets(iniAirport->country, 255, stdin);
if ((ptr = strchr(iniAirport->country, '\n')) != NULL)
*ptr = '\0';
while (!iataOk)
{
printf("IATA code:");
fgets(iniAirport->iata, TEMP_STR_LEN, stdin);
fflush(stdin);
if ((ptr = strchr(iniAirport->iata, '\n')) != NULL)
*ptr = '\0';
iataOk = checkIataOk(iniAirport->iata, airportManager);
}
return iniAirport;
}
airportMan *initAirportManager()
{
airportMan *airportManager = (airportMan *) malloc(sizeof(airportMan));
if (airportManager == NULL)
return NULL;
airportManager->airportsCount = 0;
int airportsCount = 0, i = 0;
puts("Please enter how much airports you want to add");
scanf("%d", &airportsCount);
getchar();
for (i = 0; i < airportsCount; i++)
{
airport *airport = initAirport(airportManager);
addAirport(airportManager, airport);
}
return airportManager;
}
// ****Struct date*******
struct Date
{
int day;
int month;
int year;
} typedef date_t;
bool checkDateFormat(char *dateString)
{
char tmpString[TEMP_STR_LEN] = "";
strcpy(tmpString, dateString);
char *token = strtok(tmpString, "/");
if (strlen(token) == 2)
{
token = strtok(NULL, "/");
if (strlen(token) == 2)
{
token = strtok(NULL, "/");
if (strlen(token) == 4)
return true;
puts("Please enter the date in the correct format");
return false;
}
puts("Please enter the date in the correct format");
return false;
}
puts("Please enter the date in the correct format");
return false;
}
bool checkDate(date_t *date)
{
int daysArr[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (date->month > 0 && date->month <= 12)
{
if (date->day > 0 && date->day <= daysArr[date->month - 1])
{
if (date->year >= 2020)
return true;
puts("Invalid year, please try again");
return false;
}
puts("Invalid day, please try again");
return false;
}
puts("Invalid month, please try again");
return false;
}
date_t *initDate()
{
date_t *date;
char tmpDateString[TEMP_STR_LEN];
char *ptr;
bool checkFormat = false;
bool checkValid = false;
date = (date_t *) malloc(sizeof(date_t));
while ((!checkFormat) || (!checkValid))
{
puts("Please enter date in the following format: dd/mm/yyyy ");
fgets(tmpDateString, TEMP_STR_LEN, stdin);
if ((ptr = strchr(tmpDateString, '\n')) != NULL)
*ptr = '\0';
checkFormat = checkDateFormat(tmpDateString);
char *token = strtok(tmpDateString, "/");
date->day = atoi(token);
token = strtok(NULL, "/");
date->month = atoi(token);
token = strtok(NULL, "/");
date->year = atoi(token);
checkValid = checkDate(date);
}
return date;
}
// ***Flight struct***
struct Flight
{
char departureAirport[TEMP_STR_LEN];
char arrivalAirport[TEMP_STR_LEN];
int takeofTime;
date_t *date;
} typedef flight_f;
// ***flight functions
bool checkTakeOffTime(const flight_f *flight)
{
if ((flight->takeofTime >= 0 && flight->takeofTime <= 23))
return true;
puts("Invalid time");
return false;
}
bool compareFlightIata(const char *srcIata, const char *destIata)
{
return strcmp(srcIata, destIata) == 0;
}
bool compareFlightPath(const char *srcIata, const char *destIata)
{
if (compareFlightIata(srcIata, destIata))
{
puts("Flight must have different destination and source airports ");
return false;
}
return true;
}
flight_f *initFlight(airportMan *airportManager)
{
flight_f *flight;
char *ptr;
bool checkIata = false;
bool takeoffCheck = false;
bool airportExists = false;
flight = (flight_f *) malloc(sizeof(flight_f));
puts("Please enter flight details ");
while (!checkIata || !airportExists)
{
puts("\nSrc airport:");
fgets(flight->departureAirport, TEMP_STR_LEN, stdin);
if ((ptr = strchr(flight->departureAirport, '\n')) != NULL)
*ptr = '\0';
checkIata = (checkIataSize(flight->departureAirport)
&& checkIataLetters(flight->departureAirport));
if (checkIata)
airportExists = airportFind(airportManager, flight->departureAirport);
}
checkIata = false;
airportExists = false;
while (!checkIata || !airportExists)
{
puts("\nDec airport:");
fgets(flight->arrivalAirport, TEMP_STR_LEN, stdin);
if ((ptr = strchr(flight->arrivalAirport, '\n')) != NULL)
*ptr = '\0';
checkIata = (checkIataSize(flight->arrivalAirport)
&& checkIataLetters(flight->arrivalAirport)
&& compareFlightPath(flight->departureAirport,
flight->arrivalAirport));
if (checkIata)
airportExists = airportFind(airportManager, flight->arrivalAirport);
}
while (!takeoffCheck)
{
puts("\nTakeoff time: ");
scanf("%d", &flight->takeofTime);
getchar();
takeoffCheck = checkTakeOffTime(flight);
}
flight->date = initDate();
return flight;
}
bool checkFlightPath(flight_f flight, char const *departureFrom,
char const *arrivingTo)
{
if (strcmp(flight.departureAirport, departureFrom) == 0
&& strcmp(flight.arrivalAirport, arrivingTo) == 0)
return true;
else
return false;
}
int flightPathFind(flight_f **flightsArr, char const *departureFrom,
char const *arrivingTo, int size)
{
int count = 0;
int i;
for (i = 0; i < size; i++)
{
if (checkFlightPath((*flightsArr)[i], departureFrom, arrivingTo))
{
count++;
}
}
return count;
}
// Struct airline
struct Airline
{
char name[TEMP_STR_LEN];
int filghtsCount;
flight_f **flightsArr;
} typedef airline_a;
void addFlightToAirline(airline_a *airline, airportMan *airportManager)
{
airline->flightsArr = (flight_f **) realloc(airline->flightsArr,
(airline->filghtsCount + 1) * sizeof(flight_f *));
flight_f *flightToAdd = initFlight(airportManager);
airline->flightsArr[airline->filghtsCount] = flightToAdd;
airline->filghtsCount++;
}
void airlineFlightsCount(airline_a *airline, char const *departureFrom,
char const *arrivingTo)
{
int i;
int count = 0;
for (i = 0; i < airline->filghtsCount; i++)
{
if (checkFlightPath(*(airline->flightsArr[i]), departureFrom, arrivingTo))
count++;
}
printf("%s airline has %d flights in that path\n", airline->name, count);
}
airline_a *initAirline()
{
airline_a *airline;
airline = (airline_a *)malloc(sizeof(airline_a));
if (airline == NULL)
return NULL;
char *ptr;
puts("Please enter airline name:");
fgets(airline->name, TEMP_STR_LEN, stdin);
if ((ptr = strchr(airline->name, '\n')) != NULL)
*ptr = '\0';
airline->filghtsCount = 0;
airline->flightsArr = NULL;
return airline;
}
int main()
{
airportMan *airportManager = initAirportManager();
return 0;
}
I got this errror during compile processing.
I already saw this error in this site before, I think this error can occur when the ; or something are in wrong place. but I can't find.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define MAX 80
typedef struct assemble
{
int op;
int ni;
int xbpe;
int addr;
}Assemble;
void get_token(char *bp);
int hTod(char *dp);
int bTod(char *dp);
void codeBreak(char *cp);
void result(int t);
Assemble asm;
int type;
int main()
{
FILE *fp;
char buf[MAX];
if( (fp = fopen("inst.txt","r")) == NULL ){
fprintf(stderr, "file not found...\n"); exit(1);
}
while(fgets(buf,sizeof(buf),fp) != NULL){
get_token(buf);
}
fclose(fp);
return 0;
}
void get_token(char *bp)
{
char *cp;
int i = 1;
for(cp=strtok(bp, " \t\n"); cp != NULL; )
{
if( (*(cp+0) == '0') && (*(cp+1) == 'x') )
{
if( i == -1 )
asm.addr = hTod(cp);
if( i == 1)
asm.op = hTod(cp);
i *= -1;
}
else
{
codeBreak(cp);
}
cp = strtok(NULL, " \t\n");
}
result(type);
}
void codeBreak(char *cp)
{
if ( strlen(cp) == 2 ) // ni 판단
{
asm.ni = bTod(cp);
}
else if( strlen(cp) == 1 )
{
asm.xbpe = bTod(cp)*pow(2,3);
type = 1;
}
else if( strlen(cp) == 4 )
{
if( *(cp+3) == '1')
{
asm.xbpe = bTod(cp);
type = 2;
}
else
{
asm.xbpe = bTod(cp);
type = 3;
}
}
}
void result(int t)
{
switch(t)
{
case 1 : printf("0x%x%x\n", (asm.op+asm.ni), asm.addr); break;
case 2 : printf("0x%x%x%.5x\n", (asm.op+asm.ni), asm.xbpe, asm.addr); break;
case 3 : printf("0x%x%x%.3x\n", (asm.op+asm.ni), asm.xbpe, asm.addr); break;
default : break;
}
}
/* Hex to decimal */
int hTod(char *dp)
{
int i;
int dec = 0;
for( i=2 ; i < strlen(dp) ; i++)
{
switch (*(dp+i))
{
case 'a' : *(dp+i) = 58; break;
case 'b' : *(dp+i) = 59; break;
case 'c' : *(dp+i) = 60; break;
case 'd' : *(dp+i) = 61; break;
case 'e' : *(dp+i) = 62; break;
case 'f' : *(dp+i) = 63; break;
}
dec += (*(dp+i)-48) * pow( 16, (strlen(dp)-(i+1)));
}
return dec;
}
/* binary to decimal*/
int bTod(char *dp)
{
int i;
int dec = 0;
for( i = 0; i < strlen(dp) ; i++)
{
dec += (*(dp+i)-48) * pow( 2, (strlen(dp) - (i+1)));
}
return dec;
}
asm is a keyword. Instead of
Assemble asm;
use something different, such as:
Assemble asm1;
The problem reported by the compiler is different though. You seem to have used
ASSEMBLY asm;
in the code you compiled.
So, essentially I have two files:
File 1:
//
// main.c
// frederickterry
//
// Created by Rick Terry on 1/15/15.
// Copyright (c) 2015 Rick Terry. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int size (char *g) {
int ofs = 0;
while (*(g+ofs) != '\0') {
++ofs;
}
return ofs;
}
int parse(char *g) {
// Setup
char binaryConnective;
int negated = 0;
// Looking for propositions
int fmlaLength = size(g);
if(fmlaLength == 0) {
return 1;
}
if(fmlaLength == 1) {
if(g[0] == 'p') {
return 1;
} else if (g[0] == 'q') {
return 1;
} else if (g[0] == 'r') {
return 1;
} else {
return 0;
}
}
// Now looking for negated preposition
if(fmlaLength == 2) {
char temp[100];
strcpy(temp, g);
if(g[0] == '-') {
negated = 1;
int negatedprop = parse(g+1);
if(negatedprop == 1) {
return 2;
}
}
}
// Checking if Binary Formula
char arrayleft[50];
char arrayright[50];
char *left = "";
char *right = "";
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
if(fmlaLength != 1 && fmlaLength != 2) {
if(g[0] == '-') {
int negatedBinary = parse(g+1);
if(negatedBinary == 1 || negatedBinary == 2 || negatedBinary == 3) {
return 2;
} else {
return 0;
}
}
int i = 0;
int l = 0;
int p = strlen(g);
for(l = 0; l < strlen(g)/2; l++) {
if(g[l] == '(' && g[p-l-1] == ')') {
i++;
}
}
for(int q = i; q < strlen(g); q++) {
if(g[q] == '(') {
numLeft++;
} else if(g[q] == ')') {
numRight++;
}
arrayleft[q] = g[q];
//printf("%c", arrayleft[i]);
//printf("%s", left);
if((numRight == numLeft) && (g[q+1] == 'v' || g[q+1] == '>' || g[q+1] == '^')) {
arrayleft[q+1] = '\0';
bclocation = q+1;
binaryConnective = g[q+1];
binarypresent = 1;
// printf("The binary connecive is: %c\n", binaryConnective);
break;
}
}
if(binarypresent == 0) {
return 0;
}
int j = 0;
for(int i = bclocation+1; i < strlen(g)-1; i++) {
arrayright[j] = g[i];
j++;
}
arrayright[j] = '\0';
left = &arrayleft[1];
right = &arrayright[0];
//printf("Printed a second time, fmla 1 is: %s", left);
int parseleft = parse(left);
// printf("Parse left result: %d\n", parseleft);
if(parseleft == 0) {
return 0;
}
int parseright = parse(right);
if(parseright == 0) {
return 0;
}
// printf("Parse right result: %d\n", parseleft);
if(negated == 1) {
return 2;
} else {
return 3;
}
}
return 0;
}
int type(char *g) {
if(parse(g) == 1 ||parse(g) == 2 || parse(g) == 3) {
if(parse(g) == 1) {
return 1;
}
/* Literals, Positive and Negative */
if(parse(g) == 2 && size(g) == 2) {
return 1;
}
/* Double Negations */
if(g[0] == '-' && g[1] == '-') {
return 4;
}
/* Alpha & Beta Formulas */
char binaryConnective;
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
bclocation = i+1;
binaryConnective = g[i+1];
binarypresent = 1;
break;
}
}
}
/* Connective established */
if(binaryConnective == '^') {
if(g[0] == '-') {
return 3;
} else {
return 2;
}
} else if(binaryConnective == '>') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
} else if (binaryConnective == 'v') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
}
}
return 0;
}
char bin(char *g) {
char binaryConnective;
char arrayLeft[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
int j = 0;
arrayLeft[j++] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[i+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
return binaryConnective;
}
}
}
return binaryConnective;
}
char *partone(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
for(int k = bclocation+1; k < strlen(g)-1; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
int k = 0;
k++;
return leftSide;
}
char *parttwo(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
int n = size(g) - 1;
if(g[strlen(g)-1] != ')') {
n++;
}
for(int k = bclocation+1; k < n; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
char* rightSide = &arrayRight[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
return rightSide;
}
char *firstexp(char *g) {
char* left = partone(g);
char leftArray[50];
int i = 0;
for(i; i < strlen(left); i++) {
leftArray[i] = left[i];
}
leftArray[i] = '\0';
char binConnective = bin(g);
int typeG = type(g);
if(typeG == 2) {
if(binConnective == '^') {
return &leftArray;
} else if(binConnective == '>') {
return &leftArray;
}
} else if(typeG == 3) {
if(binConnective == 'v')
return &leftArray;
}
char temp[50];
for(int i = 0; i < strlen(leftArray); i++) {
temp[i+1] = leftArray[i];
}
temp[0] = '-';
char* lefttwo = &temp[0];
if(typeG == 2) {
if(binConnective == 'v') {
return lefttwo;
}
} else if(typeG == 3) {
if(binConnective == '>' || binConnective == '^') {
return lefttwo;
}
}
return "Hello";
}
char *secondexp(char *g) {
// char binaryConnective = bin(g);
// char* right = parttwo(g);
// char rightArray[50];
// int i = 0;
// for(i; i< strlen(right); i++) {
// rightArray[i+1] = right[i];
// }
// rightArray[i] = '\0';
// int typeG = type(g);
// if(type(g) == 2) {
// if(binaryConnective == '^') {
// return &rightArray;
// }
// } else if(type(g) == 3) {
// if(binaryConnective == 'v' || binaryConnective == '>') {
// return &rightArray;
// }
// }
return "Hello";
}
typedef struct tableau tableau;
\
\
struct tableau {
char *root;
tableau *left;
tableau *right;
tableau *parent;
int closedbranch;
};
int closed(tableau *t) {
return 0;
}
void complete(tableau *t) {
}
/*int main(int argc, const char * argv[])
{
printf("Hello, World!\n");
printf("%d \n", parse("p^q"));
printf("%d \n", type("p^q"));
printf("%c \n", bin("p^q"));
printf("%s\n", partone("p^q"));
printf("%s\n", parttwo("p^q"));
printf("%s\n", firstexp("p^q"));
printf("Simulation complete");
return 0;
}*/
File 2:
#include <stdio.h>
#include <string.h> /* for all the new-fangled string functions */
#include <stdlib.h> /* malloc, free, rand */
#include "yourfile.h"
int Fsize = 50;
int main()
{ /*input a string and check if its a propositional formula */
char *name = malloc(Fsize);
printf("Enter a formula:");
scanf("%s", name);
int p=parse(name);
switch(p)
{case(0): printf("not a formula");break;
case(1): printf("a proposition");break;
case(2): printf("a negated formula");break;
case(3): printf("a binary formula");break;
default: printf("what the f***!");
}
printf("\n");
if (p==3)
{
printf("the first part is %s and the second part is %s", partone(name), parttwo(name));
printf(" the binary connective is %c \n", bin(name));
}
int t =type(name);
switch(t)
{case(0):printf("I told you, not a formula");break;
case(1): printf("A literal");break;
case(2): printf("An alpha formula, ");break;
case(3): printf("A beta formula, ");break;
case(4): printf("Double negation");break;
default: printf("SOmewthing's wrong");
}
if(t==2) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
if(t==3) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
tableau tab;
tab.root = name;
tab.left=0;
tab.parent=0;
tab.right=0;
tab.closedbranch=0;
complete(&tab);/*expand the root node then recursively expand any child nodes */
if (closed(&tab)) printf("%s is not satisfiable", name);
else printf("%s is satisfiable", name);
return(0);
}
If you look at the first file, you'll see a method called * firstexp(char * g).
This method runs perfectly, but only if another method called * secondexp(char * g) is commented out.
If * secondexp(char * g) is commented out, then *firstexp runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is -(pvq), second expansion fmla is Hello
((pvq)>-p) is satisfiableProgram ended with exit code: 0
otherwise, if *secondexp is not commented out, it runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is \240L, second expansion fmla is (-
((pvq)>-p) is satisfiable. Program ended with exit code: 0
As you can see, the outputs are completely different despite the same input. Can someone explain what's going on here?
In the commented-out parts of secondexp and in parttwo, you return the address of a local variable, which you shouldn't do.
You seem to fill a lot of ad-hoc sized auxiliary arrays. These have the problem that they might overflow for larger expressions and also that you cannot return them unless you allocate them on the heap with malloc, which also means that you have to free them later.
At first glance, the strings you want to return are substrings or slices of the expression string. That means that the data for these strings is already there.
You could (safely) return pointers into that string. That is what, for example strchr and strstr do. If you are willing to modify the original string, you could also place null terminators '\0' after substrings. That's what strtok does, and it has the disadvantage that you lose the information at that place: If you string is a*b and you modify it to a\0b, you will not know which operator there was.
Another method is to create a struct that stores a slice as pointer into the string and a length:
struct slice {
const char *p;
int length;
};
You can then safely return slices of the original string without needing to worry about additional memory.
You can also use the standard functions in most cases, if you stick to the strn variants. When you print a slice, you can do so by specifying a field width in printf formats:
printf("Second part: '%.*s'\n", s->length, s->p);
In your parttwo() function you return the address of a local variable
return rightSide;
where rightSide is a pointer to a local variable.
It appears that your compiler gave you a warning about this which you solved by making a pointer to the local variabe arrayRight, that may confuse the compiler but the result will be the same, the data in arrayRight will no longer exist after the function returns.
You are doing the same all over your code, and even worse, in the secondexp() function you return a the address of a local variable taking it's address, you are not only returning the address to a local variabel, but also with a type that is not compatible with the return type of the function.
This is one of many probable issues that your code may have, but you need to start fixing that to continue with other possible problems.
Note: enable extra warnings when compiler and listen to them, don't try to fool the compiler unless you know exactly what you're doing.
I posted a few questions about my project already and its all been helpful but I'm still unsure of one part of it.
I'm creating a translator that converts ASCII to ASH and ASH to ASCII. I have now successfully converted ASCII to ASH but can't convert from ASH to ASCII. I've created a function called 'ASCIIstring2ASHstring' which works fine, but I now have to create another function called 'ASHstring2ASCIIstring'. However, I've been told that for this function I need to save each character the user enters into a temporary buffer until a '/' appears, at which point I need to print out all the characters in the temporary buffer as a full string by calling the 'ASHstring2ASCIIstring' function (which I'm asking for help creating now) . However, I have no idea how I'd do this and I hoped someone here could lend me a hand :)
Thanks!
UPDATE: I have now created the function with some help, but for some reason its not printing out ASH to ASCII translations as expected, I have posted the updated code below.
char ASH_a[] = "*";
char ASH_b[] = "!!*";
char ASH_c[] = "!!#";
char ASH_d[] = "*!";
char ASH_e[] = "!";
char ASH_f[] = "!*!";
char ASH_g[] = "**";
char ASH_h[] = "!**";
char ASH_i[] = "!!";
char ASH_j[] = "*!!";
char ASH_k[] = "*#";
char ASH_l[] = "!*#";
char ASH_m[] = "!*";
char ASH_n[] = "!#";
char ASH_o[] = "#*";
char ASH_p[] = "!#!";
char ASH_q[] = "*!#";
char ASH_r[] = "!#*";
char ASH_s[] = "#!";
char ASH_t[] = "#";
char ASH_u[] = "##";
char ASH_v[] = "**!";
char ASH_w[] = "***";
char ASH_x[] = "*#!";
char ASH_y[] = "!##";
char ASH_z[] = "**#";
//char ASH_1[] = "#!!*";
//char ASH_2[] = "#!!#";
//char ASH_3[] = "#!*!";
//char ASH_4[] = "#!**";
//char ASH_5[] = "#!*#";
//char ASH_6[] = "#!#!";
//char ASH_7[] = "#!#*";
//char ASH_8[] = "#!##";
//char ASH_9[] = "#*!!";
//char ASH_0[] = "#!!!";
//char ASH_.[] = "#!!";
//char ASH_,[] = "#!*";
//char ASH_?[] = "#**";
//char ASH_![] = "#*#";
//char ASH_+[] = "##!";
//char ASH_-[] = "##*";
//char ASH_*[] = "###";
//char ASH_/[] = "#!#";
char t[] = "ash code";
char buffer1[100];
const int oblen = 100;
char ob [oblen];
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// Serial.println(ASH2ASCII("!**")); //These are the ASH characters I want to convert to ASCII using the ASH2ASCII function
//Serial.println(ASH2ASCII("!"));
//Serial.println(ASH2ASCII("!*#"));
//Serial.println(ASH2ASCII("!*#"));
//Serial.println(ASH2ASCII("#*"));
//ASCIIstring2ASHstring (t, ob, oblen);
//Serial.println(ob);
usinput(buffer1);
Serial.print(buffer1);
chardecide(buffer1);
}
void chardecide(char * buffer1) { //char decide which acts upon the result of isASH using the true and false returns
if (isASH (buffer1)) {
Serial.println(" has been recognized as ASH - ");
ASHstring2ASCIIstring(buffer1, ob); //passes function with buffer1 and ob included
Serial.println(ob);
} else {
Serial.println(" has been recognized as ASCII - ");
ASCIIstring2ASHstring (buffer1, ob, oblen);
Serial.println(ob);
}
}
void usinput(char * ib ) {
char inChar;
int i = 0;
do {
while (!Serial.available()) {};
inChar = Serial.read();
if (inChar == '\n') {
break;
} else {
ib[i] = inChar;
i++;
}
ib[i] = '\0';
} while (true);
}
bool isASH(char * buffer1)
{
if (buffer1[0] != '*' && buffer1[0] != '!' && buffer1[0] != '#') return false;
return true;
}
int ASHstring2ASCIIstring(char *buffer, char *ob) //converts ash to ascii
{
char str[10];
int j = 0;
int l = 0;
while (*buffer) {
if (*buffer == '/') { //hit slash
str[j] = '\0'; //empty buffer
ob[l++] = ASH2ASCII(str);
j = 0;
} else {
if (j + 1 < sizeof(str)) {
str[j++] = *buffer;
}
}
buffer++;
}
ob[l] = '\0';
return l;
}
void ASCIIstring2ASHstring (char * ip, char * op, int oplen) { //converts ascii to ash
op[0] = '\0';
int bp = 0;
int n;
char m[9];
int l = strlen(ip);
for (int i = 0; i < l; i++) {
m[0] = '\0';
strcpy(m, ASCII2ASH(ip[i]));
n = strlen(m);
if ((bp + n + l) < oplen) {
strcat(op , m);
bp = bp + n;
}
if (ip[i] != ' ' && ip[i + l] != ' ') {
op[bp] = '/';
bp++;
}
op[bp] = '\0';
}
}
char ASH2ASCII(char * m) { //Using the char variables impmented globally, ASH2ASCII searches through specific variables until it finds a match for the conversion, at which point it will capture and reuturn the ASCII string
if (strcmp(ASH_a, m) == 0) { //if string captured return a
return 'a';
}
else if (strcmp(ASH_b, m) == 0) { //else if b string is captured return
return 'b';
}
else if (strcmp(ASH_c, m) == 0) {
return 'c';
}
else if (strcmp(ASH_d, m) == 0) {
return 'd';
}
else if (strcmp(ASH_e, m) == 0) {
return 'e';
}
else if (strcmp(ASH_f, m) == 0) {
return 'f';
}
else if (strcmp(ASH_g, m) == 0) {
return 'g';
}
else if (strcmp(ASH_h, m) == 0) {
return 'h';
}
else if (strcmp(ASH_i, m) == 0) {
return 'i';
}
else if (strcmp(ASH_j, m) == 0) {
return 'j';
}
else if (strcmp(ASH_k, m) == 0) {
return 'k';
}
else if (strcmp(ASH_l, m) == 0) {
return 'l';
}
else if (strcmp(ASH_m, m) == 0) {
return 'm';
}
else if (strcmp(ASH_n, m) == 0) {
return 'n';
}
else if (strcmp(ASH_o, m) == 0) {
return 'o';
}
else if (strcmp(ASH_p, m) == 0) {
return 'p';
}
else if (strcmp(ASH_q, m) == 0) {
return 'q';
}
else if (strcmp(ASH_r, m) == 0) {
return 'r';
}
else if (strcmp(ASH_s, m) == 0) {
return 's';
}
else if (strcmp(ASH_t, m) == 0) {
return 't';
}
else if (strcmp(ASH_u, m) == 0) {
return 'u';
}
else if (strcmp(ASH_v, m) == 0) {
return 'v';
}
else if (strcmp(ASH_w, m) == 0) {
return 'w';
}
else if (strcmp(ASH_x, m) == 0) {
return 'x';
}
else if (strcmp(ASH_y, m) == 0) {
return 'y';
}
else if (strcmp(ASH_z, m) == 0) {
return 'z';
}
}
void ASCIIstring2ASH (char * buf) {
Serial.println(ASCII2ASH(*t));
}
char * ASCII2ASH (char c) { //This is the opposire of ASH2ASCII, it uses the globally defined variables to search through ASCII characters, and returns the ASH version of that character
switch (c) {
case 'a':
return ASH_a;//returns ASH version of a if matched
case 'b':
return ASH_b;
case 'c':
return ASH_c;
case 'd':
return ASH_d;
case 'e':
return ASH_e;
case 'f':
return ASH_f;
case 'g':
return ASH_g;
case 'h':
return ASH_h;
case 'i':
return ASH_i;
case 'j':
return ASH_j;
case 'k':
return ASH_k;
case 'l':
return ASH_l;
case 'm':
return ASH_m;
case 'n':
return ASH_n;
case 'o':
return ASH_o;
case 'p':
return ASH_p;
case 'q':
return ASH_q;
case 'r':
return ASH_r;
case 's':
return ASH_s;
case 't':
return ASH_t;
case 'u':
return ASH_u;
case 'v':
return ASH_v;
case 'w':
return ASH_w;
case 'x':
return ASH_x;
case 'y':
return ASH_y;
case 'z':
return ASH_z;
case ' ':
return " ";
default:
Serial.println("switching went wrong!");
break;
}
}
void loop() {
}
In <string.h>, there is a function strtok that splits a string on a range of given characters. You could use it like this:
int ASHstring2ASCIIstring(char *buffer, char *ob)
{
char *token;
int l = 0;
token = strtok(buffer, "/");
while (token) {
println(token);
ob[l++] = ASH2ASCII(token); // Note: No overflow check!
token = strtok(NULL, "/");
}
ob[l] = '\0';
return l;
}
On the first call, you supply the string to split, on subsequent calls you pass NULL to tell strtok to keep working on the same string. This code destroys the original string in the process, because it places end markers at the end of the tokens.
You can also code that behaviour yourself by filling an auxiliary buffer. When you hit a slash, process the buffer and empty it:
int ASHstring2ASCIIstring(char *buffer, char *ob)
{
char str[10];
int j = 0;
int l = 0;
while (*buffer) {
if (*buffer == '/') {
str[j] = '\0';
ob[l++] = ASH2ASCII(str);
j = 0;
} else {
if (j + 1 < sizeof(str)) {
str[j++] = *buffer;
}
}
buffer++;
}
ob[l] = '\0';
return l;
}
This code leaves the string intact. It also requires that there is a slash after the last token. That may not be what you want, but it might be a good starting point.