Thread: fgets with pointers?

  1. #1
    Registered User
    Join Date
    Nov 2008
    Posts
    10

    fgets with pointers?

    Hi,

    I'm trying to learn C, and part of an exercise is to read what the user types in and print it in the console character-by-character.

    Code:
    #include <string.h> 
    #include <stdlib.h> 
    #include <stdio.h> 
    
    int main (int argc, const char * argv[]) {
    
    	char str[256];
    	
    	printf("Please enter a long string: ");
    	
    	fgets(str, 256, stdin);
    	
    	int i;
    	for (i=0;i<256;i++) {
    		if (str[i] == '\n') {
    			str[i] = '\0';
    			break;
    		}
    	}
    	
    	for (i=0;i<strlen(str);i++)
    		printf("%d: %c\n", i, str[i]);
    	
    	getchar();
    	
    	return 0;
    }
    This works, but it would be nice not to allocate 256 characters, but only the number of character the user entered. You would do this with pointers, right? How should I modify my code?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Unfortunately, this is a little more difficult. Yes, you would use a pointer so as to use a dynamically allocated array, but the problem remains in that you don't know how many characters the user will enter until you start reading.

    One approach is to keep track of the number of characters in use (size) and the number of characters allocated (capacity). So you start with some initial capacity and read into the dynamic array, say character by character (or in blocks of characters). When the size is about to exceed the capacity, you expand the dynamic array. Finally, when you are done with reading, you resize the dynamic array for the exact number of characters required.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Also, you don't want to get in the habit of using strlen() inside a loop like this:
    Code:
        for (i=0;i<strlen(str);i++)
            printf("%d: %c\n", i, str[i]);
    It's highly ineffecient and you won't want to develop bad habits. You're basically making the computer count the number of characters in the string every time you print one of the characters. A better approach is just to see if the current character is the end-of-string marker:
    Code:
    for(i = 0;str[i] != '\0';i++)
      printf("%d: %c\n", i, str[i]);
    ...which will also help you understand walking through strings with pointers when you get there...
    Code:
    char *s;
    for(s = str;*s != '\0';s++)
      printf("%d: %c\n", s - str, *s);
    If you understand what you're doing, you're not learning anything.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by petz_e View Post
    This works, but it would be nice not to allocate 256 characters, but only the number of character the user entered. You would do this with pointers, right? How should I modify my code?
    You can do that but I seriously doubt that you'd want to. When you have to allocate and reallocate memory character by character you get into all kinds of weird issues, not the least of which is a significant degredation in performance.

    The standard practice is to allocate a buffer that is (hopefully) bigger than any string you are likely to encounter. Use this to temporarily hold the input data (from the keyboard in this case) and then copy it out of the buffer if we intend to keep it. If exact allocation sizes are important (and they most often are not) you can use malloc(strlen(string) + 1) or strdup(string) to create the necessary memory reservations.

  5. #5
    Registered User
    Join Date
    Nov 2008
    Posts
    10
    Ok I see. Thank you. The aim of the exercise is to implement some other features and functions and then to optimize these to the max (memory wise and runtime wise). That's why I was so concerned about the unused memory

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by petz_e View Post
    Ok I see. Thank you. The aim of the exercise is to implement some other features and functions and then to optimize these to the max (memory wise and runtime wise). That's why I was so concerned about the unused memory
    If you are trying to optimize for both memory and runtime, your final result will almost certainly be a compromise of some sort. Messing with memory takes time so what you gain in one you lose in the other.

    My best suggestion is that you stick with accepted practices and tweak mostly for runtime...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using fgets()
    By guillermoh in forum C Programming
    Replies: 4
    Last Post: 02-05-2008, 12:27 AM
  2. Concerning gets() and fgets()
    By ozumsafa in forum C Programming
    Replies: 20
    Last Post: 07-19-2007, 05:32 AM
  3. fgets help
    By mapunk in forum C Programming
    Replies: 4
    Last Post: 11-30-2005, 07:41 AM
  4. Using fgets()
    By Victor4015 in forum C Programming
    Replies: 4
    Last Post: 11-16-2005, 04:30 PM
  5. fgets
    By Inept Pig in forum C Programming
    Replies: 15
    Last Post: 09-12-2002, 08:27 AM