Thread: Dynamic allocation with fgets?

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    71

    Dynamic allocation with fgets?

    instead of this:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
    	FILE *poz;
    	char t[38];
    	poz=fopen("text.txt","r");
    	fgets(t,sizeof(t),poz);
    	fputs(t,stdout);
    	getch();
    }

    char *t;
    fgets(t,something,poz); //I want to allocate dynamic with fgets(Instead of "something" i do not know what to write)
    I can?
    Last edited by nutzu2010; 02-08-2011 at 01:16 PM.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Your best bet would be to allocate a large buffer for fgets() then use strdup() to allocate and copy strings out of the buffer.

    Code:
    char buffer[512];
    char *lines[100];
    
    int  main (void)
      {  FILE *file = fopen("file.txt","r"); 
          int line = 0;
       while (line < 100)
           {  fgets(buffer,511,file);
               lines[line++] = strdup(buffer);  }
    Of course it's more complex than that, but there's the gist of it.

  3. #3
    Registered User
    Join Date
    Dec 2010
    Posts
    71
    char buffer[512];
    Well it's not too much memory used?

    I do not know how big the text will be

    if read from the keyboard, it's good this code?(for FILE not something like this?)
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    int main()
    {
    	char *text;
    	t=(char*)malloc(strlen(text)+1);
    	scanf("%s",text);
    	fputs(text,stdout);
    	getch();
    }

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > if read from the keyboard, it's good this code?
    No it isn't.
    You're doing strlen() on an uninitialised pointer.

    You can't just say "here's an expandable block of memory, expand it and fill it with a file".
    You basically have to do as CommonTater said - read the file in fixed sized blocks of some sort, and then allocate space as you go.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by nutzu2010 View Post
    Well it's not too much memory used?

    I do not know how big the text will be

    if read from the keyboard, it's good this code?(for FILE not something like this?)
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    int main()
    {
    	char *text;
    	text =(char*)malloc(strlen(text)+1);
    	scanf("%s",text);
    	fputs(text,stdout);
    	getch();
    }
    The problem is that your code has to make a precition about the size of the text variable. The other method allows you to know the size before you call strdup, which mallocs the space for you.

  6. #6
    Registered User
    Join Date
    Dec 2010
    Posts
    71
    I wanted these explanations for a problem:"i have to write how many word has each sentence.A sentence is a string until she meet '\n'.
    this is the code:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int elitera(char litera);
    
    
    int  main ()
    {
    	FILE *poz;
    	char s[50];
    	int i,nrword=0;
    	poz=fopen("text.txt","r");
    	while (feof(poz)==0)
    	{
    		fgets(s,50,poz);
    		++nrword;
    		fputs(s,stdout);
    		for (i=1;i<strlen(s);++i)
    		{
    			if ( (elitera(s[i-1])==0) && (elitera(s[i])==1) )
    				++nrword;
    		}
    		printf("%d\n",nrword);
    		nrword=0;
    	}
    	getch();
    }
    
    
    int elitera(char litera)
    {
    	litera=toupper(litera);
    	if ( (litera>='A') && (litera<='Z'))
    		return 1;
    	else
    		return 0;
    }
    I have not yet put your advice into practice
    s well as I do here?
    I hope you understand

  7. #7
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Well you assume are allocate enough space to hold one line of data from the string. In most cases it wouldn't go not more than 80 bytes. But to be on safer side better to allocate more. As other have shown you.

    In order to find the nunber of words in a sentense what you need to do is, just use the strtok function to tokensise the string with the space as being your deliminator. Something like this

    Code:
        p = strtok( line, " " );
     
       while( p != NULL )
        {
            wordcount++;
             p = strtok( NULL, " ");
        }
    NOTE: strtok will alter your orginal string. So you will have to either take backup or use alternative such as using function like sscanf to tokensise the string.

    ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    easy way... scan the file line by line, count the spaces and add 1

  9. #9
    Registered User
    Join Date
    Dec 2010
    Posts
    71
    Quote Originally Posted by CommonTater View Post
    easy way... scan the file line by line, count the spaces and add 1
    I forgot to mention:may be more spaces between two words


    I thought that I can do with dynamic allocation ,that is to allocate as much memory as we need,no more

    I could not do with a pointer char?
    like:char *line;
    and allocate memory for each line
    and finally to clear the pointer for the next line( free() ) ?
    Last edited by nutzu2010; 02-09-2011 at 04:42 AM.

  10. #10
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    >I forgot to mention:may be more spaces between two words
    Just alter the following from my snap of code to support mulitple spaces.

    Code:
    p = strtok( line, "  " ); /// double space as a deliminator.
    ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  11. #11
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by nutzu2010 View Post
    I forgot to mention:may be more spaces between two words


    I thought that I can do with dynamic allocation ,that is to allocate as much memory as we need,no more

    I could not do with a pointer char?
    like:char *line;
    and allocate memory for each line
    and finally to clear the pointer for the next line( free() ) ?
    You still don't need dynamic allocation, just create a buffer large enough for a single line, then overwrite it for each new line.

    For the whitespace detection you can use isspace(). If you want to detect a variable amount of whitespace, even mixed types, you can create a function that loops over your string.

  12. #12
    Registered User
    Join Date
    Dec 2010
    Posts
    71
    ok,tanks for your answers

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Just alter the following from my snap of code to support mulitple spaces.
    > p = strtok( line, " " ); /// double space as a deliminator.
    No it doesn't.
    The second parameter is a set of characters, not a string.
    One space is the same as two spaces.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Yeah think my understanding went wrong. double space is == one space.
    @OP But strtok would still work for multiple spaces, by placing just one space in the 2 parameter, like my original code.

    ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by nutzu2010 View Post
    I forgot to mention:may be more spaces between two words


    I thought that I can do with dynamic allocation ,that is to allocate as much memory as we need,no more

    I could not do with a pointer char?
    like:char *line;
    and allocate memory for each line
    and finally to clear the pointer for the next line( free() ) ?
    If you are working line at a time with no retained data, dynamic allocation will only slow you down (it takes time to map out memory and release it later). In that scenario just make yourself a nice big buffer at program scope and re-use it...
    Last edited by CommonTater; 02-09-2011 at 09:13 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with custom dynamic memory allocation routines
    By BLauritson in forum C++ Programming
    Replies: 12
    Last Post: 03-11-2010, 07:26 AM
  2. dynamic allocation from 1 instead of zero
    By cfdprogrammer in forum C Programming
    Replies: 27
    Last Post: 04-28-2009, 08:21 AM
  3. pointer to array with dynamic allocation
    By cfdprogrammer in forum C Programming
    Replies: 22
    Last Post: 04-07-2009, 09:56 AM
  4. Difference between straight and dynamic allocation?
    By darsunt in forum C++ Programming
    Replies: 10
    Last Post: 06-04-2008, 05:47 PM
  5. Dynamic memory allocation.
    By HAssan in forum C Programming
    Replies: 3
    Last Post: 09-07-2006, 05:04 PM