1.

Solve : Problem with strcat in C?

Answer»

I am making a self extraction program in C. The code below is in a loop. Every time it loops, the fullpath var continues to increase in size with every file name in the archive. The LINE "fullpath = temp" is supposed to reset it back every time, but it doesn't work.

fullpath is a char *
temp is a char *
filename is a char[32]

Here is the part that is not working:
Code: [Select] fullpath = temp;
strcat(fullpath, filename);
ext = fopen(fullpath, "wb");
how about
Code: [Select]sprintf(fullpath, "%s/%s", temp, filename);
ext = fopen(fullpath, "wb");
remove the slash between the %s's if neccarywouldn't "fullpath=temp" simply make them point to the same variable?

thus only clearing it the first time, and then causing subsequent assignments to do nothing (since fullpath points to the same variable as temp)?Code: [Select]sprintf(fullpath, "%s/%s", temp, filename);
ext = fopen(fullpath, "wb");

I tried replacing what I had with this, but now it won't extract anything.

Quote

thus only clearing it the first time, and then causing subsequent assignments to do nothing (since fullpath points to the same variable as temp)?

During each loop filename changes. Filename is concatenated with fullpath. That's why fullpath has to be cleared each time.

Here is the full code:
Code: [Select]#include "stdio.h"
#include "stdlib.h" //Used for getenv();
#include "string.h" //Used for strcat();

int main(int ARGC, char* argv[])
{
//Make vars
FILE *self;
FILE *ext;
int lengthof;
int sum;
int fatpos;
int i;
int fcount;
char filename[32];
char *filedata;
char *temp;
char *fullpath;
CONST int F_SIZE = 6144; //Size of this program (the stub)

//Open self, set POINTER to the end of the stub
self = fopen(argv[0], "rb");
fseek(self, F_SIZE, SEEK_SET);

//Read integer for number of files in archive
fread(&fcount, sizeof(int), 1, self);

//Figure out how long the FAT is
sum = ((32 + sizeof(int)) * fcount) + sizeof(int);

//Set up the position saver thing (used to keep the position in the FAT so program can seek back after file is read)
fatpos = F_SIZE + sizeof(int);

//Get the location of the temporary directory
temp = getenv("TEMP");
if(strlen(temp) > 3)
{
strcat(temp, "\\");
}

//Loop through the file names
for(i = 0; i < fcount; i++)
{
fread(filename, 32, 1, self); //Read the file name of 32 bytes max (will auto terminate at zero byte)
fatpos += 32; //Add 32 to the position
fread(&lengthof, sizeof(int), 1, self); //Get length of file
fatpos += sizeof(int); //Add a long to the position
fseek(self, F_SIZE + sum, SEEK_SET); //Go to the file
sum += lengthof; //Add to the length for the next file to read
filedata=(char *)malloc(lengthof); //Allocate memory for file data array
fread(filedata, lengthof, 1, self); //Read the file into array
//fullpath = temp; //Set fullpath to temporary directory
//strcat(fullpath, filename); //Add the filename to the temporary directory
sprintf(fullpath, "%s/%s", temp, filename);
ext = fopen(fullpath, "wb"); //Open the file
fwrite(filedata, 1, lengthof, ext); //Write to it
fclose(ext); //Close it
fseek(self, fatpos, SEEK_SET); //Return the pointer to location in the FAT to continue reading
}
fclose(self);
return 0;
}
Quote from: Linux711 on September 07, 2009, 04:05:33 PM
During each loop filename changes. Filename is concatenated with fullpath. That's why fullpath has to be cleared each time.

Here is the full code:
Code: [Select]#include "stdio.h"
#include "stdlib.h" //Used for getenv();
#include "string.h" //Used for strcat();

int main(int argc, char* argv[])
{
//Make vars
FILE *self;
FILE *ext;
int lengthof;
int sum;
int fatpos;
int i;
int fcount;
char filename[32];
char *filedata;
char *temp;
char *fullpath;
const int F_SIZE = 6144; //Size of this program (the stub)

//Open self, set pointer to the end of the stub
self = fopen(argv[0], "rb");
fseek(self, F_SIZE, SEEK_SET);

//Read integer for number of files in archive
fread(&fcount, sizeof(int), 1, self);

//Figure out how long the FAT is
sum = ((32 + sizeof(int)) * fcount) + sizeof(int);

//Set up the position saver thing (used to keep the position in the FAT so program can seek back after file is read)
fatpos = F_SIZE + sizeof(int);

//Get the location of the temporary directory
temp = getenv("TEMP");
if(strlen(temp) > 3)
{
strcat(temp, "\\");
}

//Loop through the file names
for(i = 0; i < fcount; i++)
{
fread(filename, 32, 1, self); //Read the file name of 32 bytes max (will auto terminate at zero byte)
fatpos += 32; //Add 32 to the position
fread(&lengthof, sizeof(int), 1, self); //Get length of file
fatpos += sizeof(int); //Add a long to the position
fseek(self, F_SIZE + sum, SEEK_SET); //Go to the file
sum += lengthof; //Add to the length for the next file to read
filedata=(char *)malloc(lengthof); //Allocate memory for file data array
fread(filedata, lengthof, 1, self); //Read the file into array
//fullpath = temp; //Set fullpath to temporary directory
//strcat(fullpath, filename); //Add the filename to the temporary directory
sprintf(fullpath, "%s/%s", temp, filename);
ext = fopen(fullpath, "wb"); //Open the file
fwrite(filedata, 1, lengthof, ext); //Write to it
fclose(ext); //Close it
fseek(self, fatpos, SEEK_SET); //Return the pointer to location in the FAT to continue reading
}
fclose(self);
return 0;
}
if that didnt work
try REMOVING the / in this line "sprintf(fullpath, "%s/%s", temp, filename);"
looks like it should work though
but your not clearing the filename-

since temp is a pointer.


the first time you assign it- your clearing it- as expected. however your doing so by setting filename to point to the same address as the temp variable, so they point to the same memory location, so when you perform the assignment in future iterations, it's equal to assigning it to itself.

I'm not sure how assignments work with pointers, but I assume that without an explicit dereferencing with * it assigns the pointer rather then the value.

Anyway- did it work with smeezekitty's proposed change?I removed the / and it has a run-time error.


Discussion

No Comment Found