What I am trying to do is to parse a file (WireShark dissector into a little descriptor file) in C.
I managed to parse successfully (the values in the struct are correct), but when I write to the text file, it adds a row of null values at the end (the number of nulls added are always equal to the number of structs I wrote to the file). For example, I wrote 6 lines, so 6 nulls were added at the end.
I would love to know if someone could identify what the problem is.
This is the write macro I use:
#define WRITE_F(file_name,modifier,value) fprintf(file_name,"%"#modifier,value);
//the used function - **space_val = " "**
void write_to_file(FILE* lua_descriptor, lua_line *line)
{
WRITE_F(lua_descriptor,s, line->name);
WRITE_F(lua_descriptor,s, line->str_size);
WRITE_F(lua_descriptor,c, SPACE_VAL);
WRITE_F(lua_descriptor,d, line->opcode);
WRITE_F(lua_descriptor, s, "
");
}
//the lua_line struct:
typedef struct lua_line{
char * name;
char * str_size;
int opcode;
}lua_line;
This is handled by a client-server solution. This is the client side and I am sending it to the server like so:
/*
============================================
General : function is responsible for sending the length of the file to the server
Parameters : sock - socket connection between client and server
*filesize - holds a pointer to the size that needs to be sent
filesize_len - the length of the file size pointer
Return Value : returns TRUE when the length of the data was sent correctly.
returns FALSE when there was a socket error.
============================================
*/
bool send_file_length(SOCKET sock, long* filesize, int filesize_len)
{
bool retval = true;
unsigned char* pbuf = (unsigned char*)filesize;
int num = send(sock, pbuf, filesize_len, 0);
if (num == SOCKET_ERROR){retval = false;}
return retval;
}
/*
============================================
General : transfers the size to network byte order
and sends data to the server
Parameters : sock - socket for the client - server connection
filesize - the value of the file size
Return Value : returns TRUE when the length of the data was sent correctly.
returns FALSE when there was a socket error.
============================================
*/
bool convert_size(SOCKET sock, long filesize)
{
printf("file size %d
", filesize);
filesize = htonl(filesize);
return send_file_length(sock, &filesize, sizeof(filesize));
}
/*
============================================
General : function is responsible of sending the new lua
file to the server
Parameters : sock - socket between the client and the server
f - file that needs to be sent to the server
Return Value : returns TRUE when the file was sent correctly
returns FALSE when the file is empty or when there was a socket error
============================================
*/
bool send_file(SOCKET sock, FILE* f)
{
bool retval = true;
fseek(f, 0, SEEK_END);
long filesize = ftell(f);
char buffer[BUFFER_SIZE];
rewind(f);
if (filesize == EOF) { retval = false; }
if (retval && !convert_size(sock, filesize)) { retval = false; }
if (filesize > 0 && retval){
while (filesize > 0 && retval){
size_t num = filesize;
num = fread(buffer, 1, num, f);
if (num < 1) {
retval = false;
}
if (!send(sock, buffer, num, 0)){
retval = false;
}
filesize -= num;
}
}
return retval;
}
And on the server side, I receive and write it to the file (which adds an extra null line) like so:
/*
===================================================
General : receives the length of the file and updates it
Parameters : sock - client socket to receive the data from
*filesize - holds a pointer to the size of the buffer that needs to update
filesize_len - the length of the file size pointer
Return Value : returns TRUE when the size is read correctly
else, FALSE when there was a socket error or no bytes are received.
===================================================
*/
bool recv_file_len(SOCKET sock, long* filesize, int filesize_len)
{
unsigned char* psize = (unsigned char*)filesize;//changes the pointer type so we can receive the data to it from recv
bool retval = true;
int num = recv(sock, psize, filesize_len, 0);//receive to size
if (num == SOCKET_ERROR)
{
retval = false;
}
else if (num == 0)
{
retval = false;
}
return retval;
}
/*
===================================================
General : writes to the lua file the data from the file
that was received in the socket
Parameters : sock - the socket between the client and server
*f - the file to write the data received to
Return Value : returns TRUE when everything was written to the file.
returns FALSE if there's no data received or detected a socket problem.
===================================================
*/
bool write_to_lua(SOCKET sock, FILE *f)
{
long filesize;//size of address
char buffer[BUFFER_SIZE];
ZeroMemory(buffer, BUFFER_SIZE);
bool retval = recv_file_len(sock, &filesize, sizeof(filesize));
if (retval)//if the size of the file didn't fail to update
{
filesize = ntohl(filesize);
printf("file size (From C client) : %ld
", filesize);
while (filesize > 0 && retval)
{
int num = filesize;
if (!recv(sock, buffer, sizeof(buffer), 0))//reads the data
{
retval = false;
}
int offset = 0;
while (offset < num && retval)//writes to the file
{
size_t written = fwrite(&buffer[offset], 1, num - offset, f);
//size_t written = fprintf(f,&buffer[offset]);
if (written < 1)
{
retval = false;
}
offset += written;
}
filesize -= num;
}
}
return retval;
}
question from:
https://stackoverflow.com/questions/65922128/writing-a-struct-to-text-file-in-c