What's new

Manipulating strings in C

OP
S

Slougi

New member
aprentice said:
Stop confusing slougi with jibberish examples of your "l33t skills" :p First of all, pointers point at the address of the array holding the data. There, was that too hard to explain? :p
Yes pointers point to a mem address. I still don't see why they cannot hold any arbitrary data, and for all intends and purposes, they should be able to.
 

aprentice

Moderator
Slougi said:
Yes pointers point to a mem address. I still don't see why they cannot hold any arbitrary data, and for all intends and purposes, they should be able to.

Because the point of pointers is the point? :p
 
OP
S

Slougi

New member
aprentice said:
Because the point of pointers is the point? :p
:p


Code:
#include < stdio.h >
                                                                                                                
int main()
{
   FILE *xmms;
   char *song;
   if ((xmms = fopen("/home/louai/.xmms_song" , "r")) == NULL)
     {
        printf("Failed while loading file!\n");
        return 1;
     }
   printf("File is read!\n");
   song=(char *) malloc(sizeof(xmms));
   while (fgets(song, 200, xmms) != NULL)
     {
        printf("%s", song);
     }
   free(song);
   return 0;
}

Is anything wrong here? Again, excuse extra spaces that are due to HTML.
 
OP
S

Slougi

New member
Oh, and how would I read a file from a users home directory? Would I need to use environment variables?
Code:
fopen("~/file", "r");
Does not work.
 

aprentice

Moderator
Slougi said:
Oh, and how would I read a file from a users home directory? Would I need to use environment variables?
Code:
fopen("~/file", "r");
Does not work.

Are you coding in windows or linux?
 

euphoria

Emutalk Member
Slougi said:
:p


Code:
#include < stdio.h >
                                                                                                                
int main()
{
   FILE *xmms;
   char *song;
   if ((xmms = fopen("/home/louai/.xmms_song" , "r")) == NULL)
     {
        printf("Failed while loading file!\n");
        return 1;
     }
   printf("File is read!\n");
   song=(char *) malloc(sizeof(xmms));
   while (fgets(song, 200, xmms) != NULL)
     {
        printf("%s", song);
     }
   free(song);
   return 0;
}

Is anything wrong here? Again, excuse extra spaces that are due to HTML.

song=(char *) malloc(sizeof(xmms)); // <-- BAD!
xmms is type (FILE *) is only pointer to the file handle and its size is 4 bytes (32-bit pointer) and its not the size of the file. One way to do it is like this:

Code:
BOOL W32LoadROM(ROM_T *rom)
{
	rom->file_handle = fopen(rom->filename, "rb");
	if (!rom->file_handle)
	{
		log_error("Couldn't open %s", rom->filename);
		return FALSE;
	}
	else
	{
		size_t ret;
		struct stat sbuf;

		fstat(fileno(rom->file_handle), &sbuf);
		rom->filesize = sbuf.st_size;
		rom->filebuffer = (u8 *)malloc(rom->filesize);
		ret = fread(rom->filebuffer, 1, rom->filesize, rom->file_handle);
		fclose(rom->file_handle);
		if (ret != rom->filesize)
		{
			log_error("fread() returned wrong size!");
			return FALSE;
		}
	}
	return TRUE;
}
 

euphoria

Emutalk Member
Code:
getenv
Syntax

#include <stdlib.h>
char *getenv(const char *name);
Description
Get the setting of the environment variable name. Do not alter or free the returned value. 
Return Value
The value, or NULL if that variable does not exist. 
Portability
ANSI, POSIX 
Example

char *term = getenv("TERM");
Here's getenv() from libc-2.02 manual hope it helps
 
OP
S

Slougi

New member
euphoria said:
song=(char *) malloc(sizeof(xmms)); // <-- BAD!
xmms is type (FILE *) is only pointer to the file handle and its size is 4 bytes (32-bit pointer) and its not the size of the file. One way to do it is like this:

Code:
BOOL W32LoadROM(ROM_T *rom)
{
	rom->file_handle = fopen(rom->filename, "rb");
	if (!rom->file_handle)
	{
		log_error("Couldn't open %s", rom->filename);
		return FALSE;
	}
	else
	{
		size_t ret;
		struct stat sbuf;

		fstat(fileno(rom->file_handle), &sbuf);
		rom->filesize = sbuf.st_size;
		rom->filebuffer = (u8 *)malloc(rom->filesize);
		ret = fread(rom->filebuffer, 1, rom->filesize, rom->file_handle);
		fclose(rom->file_handle);
		if (ret != rom->filesize)
		{
			log_error("fread() returned wrong size!");
			return FALSE;
		}
	}
	return TRUE;
}


Woooh :crazy:
Wanna explain what is going on? :p
 
OP
S

Slougi

New member
Another go. Is this any good? Seems to work 100% now.

Code:
#include <stdio.h>
#include <stdlib.h>

int main()
{
   FILE *xmms;
   char *song;
   int filesize;
   if ((xmms = fopen("/home/all/slougi/.xmms_song" , "r")) == NULL)
     {
        printf("Failed while loading file!\n");
        return 1;
     }
   printf("File is read!\n");
   fseek(xmms,0,SEEK_END);
   filesize=ftell(xmms);
   rewind(xmms);
   song=(char *) malloc(filesize);
   while (fgets(song, 200, xmms) != NULL)
     {
        printf("%s", song);
     }
   fclose(xmms);
   free(song);
   return 0;
}

I am not sure whether I need to include stdlib, but was told to do it so there :p
 
OP
S

Slougi

New member
Doomulation said:
Well, I don't see any errors in it! :)
Although I prefer new and delete ;)
I'll take a look at em ;) This was just the simplest solution that I found.
 

euphoria

Emutalk Member
Slougi said:
Woooh :crazy:
Wanna explain what is going on? :p
Code:
BOOL W32LoadROM(ROM_T *rom)
{
  rom->file_handle = fopen(rom->filename, "rb");
  if (!rom->file_handle)
  {
    log_error("Couldn't open %s", rom->filename);
    return FALSE;
  }

// Above opens file and if it fails prints a error message. log_error(const char *, ...) is m own function. ignore it.

  else
  {
    size_t ret; // size_t is unsigned int
    struct stat sbuf; // struct stat is what fstat needs
    fstat(fileno(rom->file_handle), &sbuf); // get file statistics of file rom->file_handle
    rom->filesize = sbuf.st_size; // get file's size and puts it to rom->filesize
    rom->filebuffer = (u8 *)malloc(rom->filesize); // allocates memory for filebuffer
    ret = fread(rom->filebuffer, 1, rom->filesize,  rom->file_handle); // reads rom->filesize amount of bytes from rom->file_handle and puts them in rom->filebuffer
    fclose(rom->file_handle); // closes rom->file_handle ;)
    if (ret != rom->filesize) // if ret (amoun of bytes read by fread) is different from rom->filesize it prints an error message 
    {
      log_error("fread() returned wrong size!");
      return FALSE;
    }
  }
  return TRUE;
}

hope this helps a bit. i don't know how much you know about c but rom is a pointer to a structure which has elements that are accessed with '->' operator.

like:
typedef struct {
int value1;
char *pointer1;
} kakka;

and then you declare it
kakka *k;

allocate mem for it:
k = (kakka *)malloc(sizeof(kakka));

access it:
kakka->value1 = 1;
kakka->pointer1 = pointer_to_some_string_for_example;

and free it at the end:
free(kakka);
 
Last edited:
OP
S

Slougi

New member
Ok that makes it a lot clearer, thanks :) And as you can see, my C knowldge is very limited ;)

IIRC "x->y" is the same as "(*x).y", is that correct?
 

Doomulation

?????????????????????????
euphoria said:
hope this helps a bit. i don't know how much you know about c but rom is a pointer to a structure which has elements that are accessed with '->' operator.

like:
typedef struct {
int value1;
char *pointer1;
} kakka;

and then you declare it
kakka *k;

allocate mem for it:
k = (kakka *)malloc(sizeof(kakka));

access it:
kakka->value1 = 1;
kakka->pointer1 = pointer_to_some_string_for_example;

and free it at the end:
free(kakka);
I find it just easier to use new/delete.
Code:
typedef struct {
  int value1;
  char *pointer1;
} kakka;

int main()
{
  kakka* k = new kakka;
  or...
  kakka* k = new kakka[arrays];

  delete k;
  or...
  delete [] k;
}

I think it's possible in c. It should be ;) it works at least with vc++.
Anyway, when using delete, use the seconds statement to delete arrays of the pointer. Otherwise youuse the first statement.
 

Top