Problems writing to 2-Dimensional arrays, Embedded C - c

I am having trouble understanding what is going on with my code, mainly regarding 2D arrays. I am trying to use a function in my communication file to decode a command string from a terminal. I want it to break the string down and output the answers by updating the global buffers. I am having trouble writing to these arrays and I do not understand why. In the code below I just assigned a value to the USART1_Command char array where in the actual program it comes from a terminal.
Main and declarations:
//Global declarations//
#define USART1_BUFFER_SIZE (100)
#define MAX_COMMAND_INT_VALUES (50)
#define MAX_COMMAND_STR_VALUES (50)
#define MAX_COMMAND_STR_LENGTH (50)
char USART1_Buffer[USART1_BUFFER_SIZE];
uint16_t USART1_Write_Index = 0;
char USART1_Command[MAX_COMMAND_STR_LENGTH] = {0x00};
uint16_t USART1_Command_Int_Values[MAX_COMMAND_INT_VALUES] = {0x00};
char **USART1_Command_Str_Values;
void main(void){
USART1_Command_Str_Values = (char **)calloc(MAX_COMMAND_STR_VALUES, sizeof(char *));
uint16_t i = 0;
for(i = 0; i < MAX_COMMAND_INT_VALUES; i++){
USART1_Command_Str_Values[i] = (char *)calloc(MAX_COMMAND_STR_LENGTH, sizeof(char));
}
strcpy(USART1_Command, "TESTCOMMAND,45,36,21-TEST1-TEST2");
USART1_Command_Decode(USART1_Command, USART1_Command_Int_Values, USART1_Command_Str_Values, MAX_COMMAND_INT_VALUES, MAX_COMMAND_STR_VALUES, MAX_COMMAND_STR_LENGTH);
while(1){
}
}
and the function:
void USART1_Command_Decode(char *command, uint16_t *int_values_buffer, char **str_values_buffer, uint16_t int_values_buffer_size, uint16_t str_values_buffer_size, uint16_t str_values_size){
uint16_t i = 0;
uint16_t j = 0;
uint16_t length = strlen(command);
int16_t Int_Values_Index = -1;
bool Int_Value_Flag = false;
char **Int_Values;
Int_Values = (char**)calloc(int_values_buffer_size, sizeof(char*));
for(i = 0; i < int_values_buffer_size; i++){
Int_Values[i] = (char*)calloc(str_values_size, sizeof(char));
}
const uint16_t Max_Str_Values = 50;
int16_t Str_Values_Index = -1;
bool Str_Value_Flag = false;
for(i = 0; i < length; i++){
switch(command[i]){
case ',': //Signifies integer value//
if(Int_Values_Index < int_values_buffer_size){
Int_Values_Index++;
Int_Value_Flag = true;
Str_Value_Flag = false;
j = 0;
}
command[i] = 0x00;
break;
case '-': //Signifies string value//
if(Str_Values_Index < str_values_buffer_size){
Str_Values_Index++;
Str_Value_Flag = true;
Int_Value_Flag = false;
j = 0;
}
command[i] = 0x00;
break;
default:
if(Int_Value_Flag){
Int_Values[Int_Values_Index][j] = command[i];
command[i] = 0x00;
j++;
}
if(Str_Value_Flag){
str_values_buffer[Str_Values_Index][j] = command[i];
command[i] = 0x00;
j++;
}
break;
}
}
//Convert integer strings to integers//
for(i = 1; i <= Int_Values_Index; i++){
int_values_buffer[i] = atoi(Int_Values[i]);
}
for(i = 0; i < int_values_buffer_size; i++){
free(Int_Values[i]);
}
free(Int_Values);
}

I figured this out, the way that I was able to make it work was as follows:
Declaration of Global variables:
#define MAX_COMMAND_INT_VALUES (50)
#define MAX_COMMAND_STR_VALUES (50)
#define MAX_COMMAND_STR_LENGTH (50)
char USART1_Command[MAX_COMMAND_STR_LENGTH] = {0x00};
uint16_t USART1_Command_Int_Values[MAX_COMMAND_INT_VALUES] = {0x00};
char USART1_Command_Str_Values[MAX_COMMAND_STR_VALUES][MAX_COMMAND_STR_LENGTH];
Function:
void USART1_Command_Decode(char *command, uint16_t *int_values_buffer, uint16_t int_values_buffer_size, uint16_t str_values_buffer_size, uint16_t str_values_size, char str_values_buffer[str_values_buffer_size][str_values_size]){
uint16_t i = 0;
uint16_t j = 0;
uint16_t length = strlen(command);
int16_t Int_Values_Index = -1;
bool Int_Value_Flag = false;
char Int_Values[int_values_buffer_size][str_values_size];
for(i = 0; i < int_values_buffer_size; i++){
for(j = 0; j < str_values_size; j++){
Int_Values[i][j] = 0x00;
}
}
int16_t Str_Values_Index = -1;
bool Str_Value_Flag = false;
for(i = 0; i < length; i++){
switch(command[i]){
case ',': //Signifies integer value//
if(Int_Values_Index < int_values_buffer_size){
Int_Values_Index++;
Int_Value_Flag = true;
Str_Value_Flag = false;
j = 0;
}
command[i] = 0x00;
break;
case '-': //Signifies string value//
if(Str_Values_Index < str_values_buffer_size){
Str_Values_Index++;
Str_Value_Flag = true;
Int_Value_Flag = false;
j = 0;
}
command[i] = 0x00;
break;
default:
if(Int_Value_Flag){
Int_Values[Int_Values_Index][j] = command[i];
command[i] = 0x00;
j++;
}
if(Str_Value_Flag){
str_values_buffer[Str_Values_Index][j] = command[i];
command[i] = 0x00;
j++;
}
break;
}
}
//Convert integer strings to integers//
for(i = 0; i <= Int_Values_Index; i++){
int_values_buffer[i] = atoi(Int_Values[i]);
}
}
Function Call:
USART1_Command_Decode(USART1_Command, USART1_Command_Int_Values, MAX_COMMAND_INT_VALUES, MAX_COMMAND_STR_VALUES, MAX_COMMAND_STR_LENGTH, USART1_Command_Str_Values);
Thank you #P__J__ for the help!
EDIT:
I found the main problem with my original code, I was having problems with stack overflow because I was misunderstanding the allocation for stack and heap in Cross Studio. I had 256bytes of stack when I thought that I had more like 20KB. I allocated 16KB to stack and 8KB to heap, all the problems with malloc() and calloc() have disappeared along with the array writing issues. I apologize to everyone for the unnecessary question.

Related

Error passing by reference when making os

I am making an os and have booted into a 64 bit kernel made in c. I have made a print function which is working and am trying to make a function to convert hex values to string so I can print them. My code is causing boot loops, yet when I compile the exact same code to run normally in linux it works perfectly. The relevant code:
int logarithm(double value, int base, int* output) {
int i = 0;
while (value > 1) {
value /= base;
i++;
}
*output = i;
}
int power(int value, int power, int* output) {
if (power == 0) {
value = 1;
} else {
for (int i = 0; i < (power - 1); i++) {
value *= value;
}
}
*output = value;
}
void hexToStr(unsigned int hex, char** string) {
int hexLength = 0;
logarithm((double)hex, 16, &hexLength);
char output[hexLength];
output[hexLength] = 0;
int powerValue = 0;
for (int i = 0; i < hexLength; i++) {
power(16, i, &powerValue);
output[hexLength - i - 1] = (hex & (powerValue * 15)) / powerValue + '0';
}
*string = output;
}
If I change the hexToStr() function code to this (removing the need for logarithm() and power() functions by hardcoding values for the string), it works in both linux and my kernel:
void hexToStr(unsigned int hex, char** string) {
int hexLength = 10;
char output[hexLength];
output[hexLength] = 0;
int powerValue = 0;
for (int i = 0; i < hexLength; i++) {
output[hexLength - i - 1] = 'A';
}
*string = output;
}
Any suggestions as to why this would happen?
The presented code invokes undefined behavior. For example let's consider this function
void hexToStr(unsigned int hex, char** string) {
int hexLength = 10;
char output[hexLength];
output[hexLength] = 0;
int powerValue = 0;
for (int i = 0; i < hexLength; i++) {
output[hexLength - i - 1] = 'A';
}
*string = output;
}
In this assignment statement:
output[hexLength] = 0;
there is written data outside the array because the valid range of indices is [0, hexLength).
Or the function sets a pointer passed to the function by reference to the local array output that will not be alive after exiting the function. So the returned pointer will have an invalid value.
Another example the result value of the function power when the parameter value is equal to 3 and the parameter power is equal to 3 will be equal to 81 instead of 27 due to the assignment statement in this for loop.
for (int i = 0; i < (power - 1); i++) {
value *= value;
}
Moreover the function returns nothing though its return type is not void.
int power(int value, int power, int* output) {
Also this expression
(hex & (powerValue * 15)) / powerValue + '0'
does not make a sense.
Needed to enable SSE unit to work with floats and doubles. As well as change how values are passed back. Working code:
void log(float value, float base, uint64_t* output) {
uint64_t i = 0;
while (value >= 1) {
value /= base;
i++;
}
*output = i;
}
void pow(uint64_t value, uint64_t exponent, uint64_t* output) {
uint64_t result = 1;
for (uint64_t i = 0; i < exponent; i++) {
result = result * value;
}
*output = result;
}
void hexToStr(uint64_t hex, char* output) {
uint8_t hexLen = 16;
log((float)hex, (float)16, &hexLen);
char result[hexLen + 3];
result[0] = '0';
result[1] = 'x';
result[hexLen + 2] = 0;
uint64_t powerValue = 1;
for (uint8_t i = 0; i < hexLen; i++) {
pow(16, i, &powerValue);
result[hexLen - i + 1] = (hex & (uint64_t)(powerValue * (uint64_t)15)) / powerValue + '0';
}
for (uint8_t i = 0; i < hexLen + 3; i++) {
switch(result[i]) {
case ':':
result[i] = 'A';
break;
case ';':
result[i] = 'B';
break;
case '<':
result[i] = 'C';
break;
case '=':
result[i] = 'D';
break;
case '>':
result[i] = 'E';
break;
case '?':
result[i] = 'F';
break;
}
output[i] = result[i];
}
}

How can I take this values to an array?

I am trying to take this input from terminal.
ARRAY [1,2,3,4,5,6]
and pass the numbers to an array like this.
else if (strncmp(input, "CONSTRUCT", 9) == 0) {
printf("CONSTRUCT\n");
// CONSTRUCT [value1,value2,value3,...,valueN]
int i = 0;
char *token;
char *str = strdup(input);
char **array = str_split(str, '[');
char **array2 = str_split(array[1], ']');
char **array3 = str_split(array2[0], ',');
int array4[100];
for (i = 0; i < 100; i++){
array4[i] = atoi(array3[i]);
}
for (i = 0; i < 100; i++){
printf("%d\n", array4[i]);
}
for (i = 0; i < 100; i++){
root = insert(root, array4[i]);
}
printf("\n");
}
here you simply run off the end of an array
char** array3 = str_split(array2[0], ',');
int array4[100];
for (i = 0; i < 100; i++)
{
array4[i] = atoi(array3[i]);
}
array3 is dynamically sized to number of numbers + 1, but you try to access 100 entries
you placed a null entry at the end of the list, use that
int count = 0;
for (i = 0; i < 100; i++)
{
if (array3[i] == NULL)
break;
count++;
array4[i] = atoi(array3[i]);
}
for (i = 0; i < count; i++)
{
printf("%d\n", array4[i]);
}
for (i = 0; i < count; i++)
{
root = insert(root, array4[i]);
}
I saw your comment about the space. this code does not work with a space after 'CONSTRUCT', thats because
scanf("%s", input);
reads up to the first space - you want fgets.

pass multiple values from a function defined in one file to another file using c

I have a task get multiple values from one function defined in one.c file to other function defined in two.c file.
Please find below code snippet from both the files and kindly help to access the values from one.c file into two.c file.
file one.c:
void GetABFWversion(uint8_t* fwcommand, uint8_t* fwaction, uint16_t* fwvalue)
{
uint16_t FW_slot=SdusAutoDetectSlotForNewFirmware();
char MyCopy[10];
strcpy (MyCopy, BrakeBoardInfo.firmwareVersion);
char MyCopy1[10];
for (int k=0; k<9; k++)
{
int l=1;
MyCopy1[k] = MyCopy[k+l];
}
char FWversion_AB[10] = {0};
int z = 0;
for(int x=6;x<10;x++)
{
FWversion_AB[z] = MyCopy1[x];
z++;
}
char res=0;
uint16_t val = atoi(FWversion_AB);
//res = proto485OnlyWrite(0x09,0x02,0x00,val);
printf("\n");
printf("FW version is sent to Arduino!!! ");
RESULT = 1;
*fwcommand = 0x02;
*fwaction = 0x00;
*fwvalue = val;
}
file two.c:
int16_t driver485Read (uint8_t *buffer, const uint16_t length)
{
char head[20];
const char *format="KL%02x:";
int16_t wait_loop_cnt=0;
static uint32_t totalBytes = 0;
static uint32_t respNo = 0;
GPIO_ClearValue(PMAP_GPIO_PORT_DIR_RS485, PMAP_GPIO_PIN_DIR_RS485);
UartRxFlush(UARW_UART_INDEX_RS485); /
respNo++;
int counter = 0;
do
{
OSTimeDly(2);
int8_t newBytesRcv = UartReceive(UARW_UART_INDEX_RS485,
(uint8_t*)&(buffer[counter]), length-counter);
totalBytes += newBytesRcv;
counter = totalBytes;
}
while (/*wait_loop_cnt++<= MAX_WAIT_LOOP &&*/ counter < length);
totalBytes = 0;
uint8_t i = 0;
format="OK%02x:";
printf("Byte received........");
int FWmsg[9] = {0x09,0x30,0x30,0x32,0x32,0x31,0x31,0x31,0x31};
int arduinodata[9] = {0x09,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30};
for (i=0; i<9;i++)
{
printf("%d ",buffer[i]);
arduinodata[i] = buffer[i];
}
if(compareArray(FWmsg,arduinodata,7)==0)
{
printf("Arrays have same elements.\n");
printArray(FWmsg,9);
char res = 0;
uint8_t fwc, fwa;
uint16_t fwv;
GetABFWversion(&fwc, &fwa, &fwv);
res = proto485OnlyWrite(0x09,fwc,fwa,fwv);
printf("\n");
printf("FW version is sent to Arduino!!! ");
}
else
{
printf("Arrays have different elements.\n");
}
/* 1st byte is the slave address byte which value should be >= RS485_ADDRESS_SLAVE_FIRST &&
<= RS485_ADDRESS_SLAVE_LAST and is already checked in dePadLeft() */
for(int i = 1; i < length && buffer[i] >= RS485_PAYLOAD_VALID_MIN && buffer[i] <= RS485_PAYLOAD_VALID_MAX; i++);
counter = i; // to be OK, i = length = RS485_MSG_LENGTH if response (after eventual dePad..) is OK
printf("driver485Read %d\n",counter);
#ifdef RS485_DEBUG
static uint32_t i = 0;
i++;
#endif
return counter;
GPIO_SetValue(PMAP_GPIO_PORT_DIR_RS485, PMAP_GPIO_PIN_DIR_RS485);
}
file three.c:
uint8_t proto485OnlyWrite(uint8_t address, uint8_t command, uint8_t action, uint16_t value)
{
uint8_t res=ERROR_FOUND;
OSSemPend(pbSemaphore, 0, &res);
if (res == OS_ERR_NONE)
{
rs485_message_t rs485Msg;
if (command ==CMD_POWER_PUMP_PB)
{
printf("CMD_POWER_PUMP_PB");
}
proto485ComposeMsg(&rs485Msg, address, command, action, value);
res = (RS485_MSG_LENGTH == driver485Write((uint8_t *)&rs485Msg, sizeof(rs485Msg))) ?
NO_ERROR:
ERROR_FOUND;
OSSemPost(pbSemaphore);
}
return res;
}
I want to get the values of "fwcommand", "fwaction" and "fwvalue" defined in file one.c into file two.c at the place where I am passing the same to "res = proto485OnlyWrite(0x09,fwc,fwa,fwv);" in the place of "fwc", "fwa" and "fwv" respectively.
Thank you....

C rename() can't seem to get it to work

I'm trying to make a program that takes in a database of listfile names and compare it with another list. When there is a match it should rename the file with that name to the corresponding relationNumber.
At the end of the code I try to rename the file, but it doesn't let me. Is it because I'm trying to pass chars instead of const chars? And if so, how can I solve this? Before I try to rename the file I printed the strings out to see what is in them and the strings contain; "Zaalstra legitimatie.txt" and "1.17234842.txt" which is what I want. Thanks in advance.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define relationLen 10
#define true 1
#define false 0
#define resetptr NULL
typedef int bool;
char* strcasestr(char* haystack, char* needle) {
size_t i, j;
if (!needle[0])
return (char*) haystack;
for (i = 0; haystack[i]; i++) {
bool matches = true;
for (j = 0; needle[j]; j++) {
if (!haystack[i + j])
return NULL;
if (tolower((unsigned char)needle[j]) != tolower((unsigned char)haystack[i + j])) {
matches = false;
break;
}
}
if (matches)
return (char *)(haystack + i);
}
return NULL;
}
int main(void) {
char database[1024][30];
char name[30] = {0};
char newName[30] = {0};
char extension[1024][5];
char lined[256], linef[256];
char relationNumber[] = "1.1";
char newRelationNumber[relationLen] = {0};
char *ret, *number;
int i, j, c, k, len = 0;
FILE* filef = fopen("filelist.txt", "r");
for(i = 0; (c = fgetc(filef)) != EOF; i++) {
fgets(linef, sizeof(linef), filef);
strcpy(database[i], (char[2]){(char) c, '\0'});
strcat(database[i], linef);
len = strlen(database[i]);
for(j = 0, k = 5; j < 4; j++, k--) {
extension[i][j] = database[i][len-k];
}
printf("%s ", extension[i]);
printf("%s", database[i]);
}
FILE* filed = fopen("Database.txt", "r");
fgets(lined, sizeof(lined), filed);
printf("%s", lined);
number = strstr(lined, relationNumber);
for(i = 0; lined[i] != 9; i++)
newName[i] = lined[i];
newName[i] = '\0';
for(i = 0; i < relationLen; i++)
newRelationNumber[i] = number[i];
newRelationNumber[i] = '\0';
number = resetptr;
strcat(newRelationNumber, ".txt");
ret = strcasestr(database[i], newName);
printf("%s", database[0]);
printf("%s", newRelationNumber);
i = rename(database[0], newRelationNumber);
printf("\n%d", i);
return 0;
}

Passing a string array to a function to be altered

so currently I am running a program to generate a bundle of files at random, then have them connect to each other, and create a maze like game.
I'm trying to build an array of the file paths to pass to a function so it can be generated then the array can be worked on some more by the calling function. What's happening is that is generating the array but leaving the first element(filepath[0]) blank thus seg. faulting on me. But when I set a breakpoint, all other sections of the array are fine, just not the first element. It's been about 9 months since I wrote and C and I'm unsure where my pointer hiccup is coming from, thank you all in advanced
Here is the code so far
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <stdbool.h>
void create_files(char (*filepath[7]));
int main(){
time_t t;
char *filepath[7];
srand((unsigned) time(&t));
int i = 0;
for (i = 0; i < 7; i++)
filepath[i] = malloc(60);
create_files(filepath);
for (i = 0; i < 7; i++)
free(filepath[i]);
return 0;
}
void create_files(char (*filepath[7])){
int i = 0, pid = getpid(),q = 0,random, r=7;
char procid[20];
sprintf(procid, "%d", pid);
char directory[80] = "./dringb.rooms.";
strcat(directory,procid);
int newdir = mkdir(directory, 0777);
for (q = 0; q < 7; q++)
filepath[q] = directory;
char *bigrooms[10] ={"/Bridge.txt","/Gate.txt","/Hallway.txt",
"/Dungeon.txt","/Galley.txt","/Throne.txt","/Boss.txt", "/Lab.txt",
"/Torture.txt", "/Courtyard.txt"};
bool redflag = false;
char *rooms[7];
q = 0;
while (q != 7){ //grabs the rooms at random from the set of bigrooms
random = rand()%10;
for(i = 0; i < 7; i++){
if (rooms[i] == bigrooms[random])
redflag = true;
}
if (redflag == false){
rooms[q] = bigrooms[random];
redflag = false;
q++;
}
else
redflag = false;
}
char **dest = (char **)malloc(r * sizeof(char *));
for (i=0; i<r; i++)
dest[i] = (char *)malloc(8 * sizeof(rooms)); //allocates each room a new space
for (i = 0; i < 7; i++){
strcat(dest[i], directory);
strcat(dest[i],rooms[i]);
filepath[i] = dest[i]; //creates directory path for each room.txt
}
int usedrooms[4];
for (i = 0; i < 7; i++){
FILE *f = fopen(filepath[i], "w");
fputs("Roomname: ", f);
fputs(rooms[i],f);
fputs("\n",f);
fclose(f);
}
for (i = 0; i < 7; i++){
FILE *f = fopen(filepath[i], "a+");
for (q = 0; q < 4; q++)
usedrooms[q] = 100;
int roomrand, q = 0, z = 0, connrooms = 3;
bool greenflag = true, retry = false;
roomrand = rand() %2;
if (roomrand == 1)
connrooms = 4;
while (q != connrooms){ //prevents from having a connection to same room
do{
retry = false;
roomrand = rand() % 7;
for(z = 0; z < 4; z++){
if (roomrand == usedrooms[z])
retry = true;
}
}while(roomrand == i || retry == true); //prevents from having a connection to same room
bool found = false;
char buffer[100];
rewind(f);
while(fscanf(f,"%s", buffer) == 1){
if (strcmp(buffer,rooms[roomrand]) == 0)//prevents a double connecting room from being added
greenflag = false;
}
if(greenflag == true){
usedrooms[q] = roomrand;
fputs("Connecting Room: ", f);
fputs(rooms[roomrand],f);
fputs("\n",f);
}
fclose(f);
greenflag = true;
found = false;
FILE *f2 = fopen(filepath[roomrand],"a+");
rewind(f2);
while(fscanf(f2,"%s", buffer) == 1){
if (strcmp(buffer,rooms[i]) == 0) //prevents a double connecting room from being added
found = true;
}
if (found == false){
fputs("Connecting Room: ",f2);
fputs(rooms[i],f2);
fputs("\n",f2);
}
fclose(f2);
fopen(filepath[i],"a+");
found = false;
q++;
}
q = 0;
fclose(f);
}
int usedroomtype[7];
int roomrand;
for (i = 0; i < 7; i++)
usedroomtype[i] = 100;
for (i = 0; i < 7;i++){
do{
redflag = false;
roomrand = rand() % 7;
for (q = 0; q < 7; q++)
if (roomrand == usedroomtype[q])
redflag = true;
} while (redflag == true);
usedroomtype[i] = roomrand;
FILE *fp = fopen(filepath[roomrand], "a+");
if (i == 0)
fputs("Room Type: Start Room", fp);
else if (i == 6)
fputs("Room Type: End Room",fp);
else
fputs ("Room Type: Mid Room",fp);
fclose(fp);
}
}
The array is being passed correctly. The problem is that data is getting corrupted.
for (q = 0; q < 7; q++)
filepath[q] = directory;
This is invalid. It should be strcpy(filepath[q], directory); It's okay to set for example char *temp = filepath[q], because temp was not allocated. But filepath[q] is already allocated. Use strcpy to to change it value.
Later there is a similar error
char **dest = (char **)malloc(r * sizeof(char *));
for (i=0; i<r; i++)
dest[i] = (char *)malloc(8 * sizeof(rooms));
for (i = 0; i < 7; i++){
strcat(dest[i], directory);
strcat(dest[i],rooms[i]);
filepath[i] = dest[i]; //creates directory path for each room.txt
}
Two things. First, dest is not initialized. Always start with strcpy with uninitialized string, then use strcat. Second, use strcpy to change the value of filepath[i] as explained earlier. dest is actually not needed. You could just copy directly to filepath
for (i = 0; i < 7; i++)
{
strcpy(filepath[i], directory);
strcat(filepath[i], rooms[i]);
}
As mentioned in comments, allocation for filepath should be larger. directory is max 80 bytes, room is max 10 bytes, so filepath should be max 90 bytes.
for (i = 0; i < 7; i++)
filepath[i] = malloc(90);
Also some values are not initialized, example char *rooms[7];
Elsewhere:
int pid = getpid();
char procid[20];
sprintf(procid, "%d", pid);
char directory[80] = "./dringb.rooms.";
strcat(directory,procid);
You are already using sprintf, you can simplify this as follows:
sprintf(directory, "./dringb.rooms.%d", getpid());
Example:
int main()
{
time_t t;
srand((unsigned) time(&t));
char *filepath[7];
int i = 0;
for (i = 0; i < 7; i++)
filepath[i] = malloc(90);
create_files(filepath);
for (i = 0; i < 7; i++)
printf("%s\n", filepath[i]);
for (i = 0; i < 7; i++)
free(filepath[i]);
return 0;
}
void create_files(char *filepath[7])
{
int i = 0, random;
char directory[80];
sprintf(directory, "./dringb.rooms.%d", getpid());
//mkdir(directory);
mkdir(directory, 0777);
int q;
for (q = 0; q < 7; q++) strcpy(filepath[q], directory);
char *bigrooms[20] ={"/Bridge.txt","/Gate.txt","/Hallway.txt","/Dungeon.txt","/Galley.txt","/Throne.txt","/Boss.txt", "/Lab.txt","/Torture.txt", "/Courtyard.txt"};
bool redflag = false;
char *rooms[7];
for (i = 0; i < 7; i++) rooms[i] = 0;
q = 0;
while (q != 7)
{
//grabs the rooms at random from the set of bigrooms
random = rand()%10;
for(i = 0; i < 7; i++)
{
if (rooms[i] == bigrooms[random])
redflag = true;
}
if (redflag == false)
{
rooms[q] = bigrooms[random];
redflag = false;
q++;
}
else
redflag = false;
}
for (i = 0; i < 7; i++)
{
strcpy(filepath[i], directory);
strcat(filepath[i], rooms[i]);
}
int usedrooms[4];
for (i = 0; i < 7; i++)
{
FILE *f = fopen(filepath[i], "w");
fputs("Roomname: ", f);
fputs(rooms[i],f);
fputs("\n",f);
fclose(f);
}
for (i = 0; i < 7; i++)
{
FILE *f = fopen(filepath[i], "a+");
for (q = 0; q < 4; q++)
usedrooms[q] = 100;
int roomrand, q = 0, z = 0, connrooms = 3;
bool greenflag = true, retry = false;
roomrand = rand() %2;
if (roomrand == 1)
connrooms = 4;
while (q != connrooms)
{ //prevents from having a connection to same room
do
{
retry = false;
roomrand = rand() % 7;
for(z = 0; z < 4; z++)
{
if (roomrand == usedrooms[z])
retry = true;
}
}
while(roomrand == i || retry == true); //prevents from having a connection to same room
bool found = false;
char buffer[100];
rewind(f);
while(fscanf(f,"%s", buffer) == 1)
{
if (strcmp(buffer,rooms[roomrand]) == 0)//prevents a double connecting room from being added
greenflag = false;
}
if(greenflag == true)
{
usedrooms[q] = roomrand;
fputs("Connecting Room: ", f);
fputs(rooms[roomrand],f);
fputs("\n",f);
}
fclose(f);
greenflag = true;
found = false;
FILE *f2 = fopen(filepath[roomrand],"a+");
rewind(f2);
while(fscanf(f2,"%s", buffer) == 1)
{
if (strcmp(buffer,rooms[i]) == 0) //prevents a double connecting room from being added
found = true;
}
if (found == false)
{
fputs("Connecting Room: ",f2);
fputs(rooms[i],f2);
fputs("\n",f2);
}
fclose(f2);
fopen(filepath[i],"a+");
found = false;
q++;
}
q = 0;
fclose(f);
}
int usedroomtype[7];
int roomrand;
for (i = 0; i < 7; i++)
usedroomtype[i] = 100;
for (i = 0; i < 7; i++)
{
do
{
redflag = false;
roomrand = rand() % 7;
for (q = 0; q < 7; q++)
if (roomrand == usedroomtype[q])
redflag = true;
}
while (redflag == true);
usedroomtype[i] = roomrand;
FILE *fp = fopen(filepath[roomrand], "a+");
if (i == 0)
fputs("Room Type: Start Room", fp);
else if (i == 6)
fputs("Room Type: End Room",fp);
else
fputs ("Room Type: Mid Room",fp);
fclose(fp);
}
}

Resources