Thread: must use pointers, not arrays

  1. #1
    Registered User
    Join Date
    Sep 2009
    Location
    San Antonio, TX
    Posts
    9

    must use pointers, not arrays

    Hello, so I'm trying to write a C program for an assignment. It consists of 3 files: driver.c, sreplace.c, and *strmatch.c

    sreplace is supposed to take a character string from driver and replace each instance of a character with a new one.
    *strmatch will find the first occurance of the string s in the string str and will return the pointer to the first match if a match occurs, else it returns NULL

    the instructions are as follows:


    In this assignment you are to write two C functions, each in its own file and a main driver program. The functions are to only use pointers, there should be no arrays in any of the functions. You will, of course, need to define a character array in which to read the input in your main driver program.

    I had not noticed the bold part when I wrote and tested sreplace but am not sure if I am even breaking the requirements since I'm new to the whole pointer concept.


    the prototype for sreplace is

    Code:
    int sreplace(char newc, char oldc, char *s);

    and here is my sreplace:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    int sreplace(char newc, char oldc, char *s){
    	int numReplaced = 0;
    	int i = 0;
    	for (i; i <= strlen(s); i++){
    		if (s[i] == oldc){
    			s[i] = newc;
    			numReplaced++;
    		}
    
    	}
    	
    
    
    
    	return numReplaced;
    	// return number of replacements made
    }
    from what i tested, this works like it should, but i believe i shouldn't use an array
    how would i go about changing it? i'm not too familiar with pointers - i know there are ways to increment s and not *s but if you could help me with knowing the difference and what I need to do to fix my code I'd be very greatful

  2. #2
    Registered User
    Join Date
    Sep 2009
    Location
    San Antonio, TX
    Posts
    9
    I think I may have fixed it to work with pointers (after scanning the FAQ):

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    int sreplace(char newc, char oldc, char *s){
    	int numReplaced = 0;
    	int i = 0;
    	for (i; i <= strlen(s); i++){
    		if (*s == oldc){
    			*s = newc;
    			numReplaced++;
    		}
                    *(s++);
    
    	}
    	
    
    
    
    	return numReplaced;
    	// return number of replacements made
    }

    i believe this increments in the same way as my array implementation, but feedback would be appreciated

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by cubis View Post
    I think I may have fixed it to work with pointers (after scanning the FAQ):

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    int sreplace(char newc, char oldc, char *s){
    	int numReplaced = 0;
    	int i = 0;
    	for (i; i <= strlen(s); i++){
    		if (*s == oldc){
    			*s = newc;
    			numReplaced++;
    		}
                    *(s++);
    
    	}
    	
    
    
    
    	return numReplaced;
    	// return number of replacements made
    }

    i believe this increments in the same way as my array implementation, but feedback would be appreciated
    Youonly need to increment s, not dereference it. s++; will do for that.

    You've introduced a bug though. when you increment s then taking strlen of s will give an answer smaller by 1. However you don't want to recalculate the strlen each time through the loop anyway, and hoisting that out will fix the bug.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Actually you don't even need to use strlen. Your loops should just step through the characters until you find the nul-terminator.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    A pointer is a variable. It holds an address. Do not think of a pointer as anything else.
    You can assign addresses to pointers. You can also increment pointers, so the address it points to increments. This is useful when working with arrays, since when incrementing the address, it would point to the address where the next element lies.
    To read or write the actual value at the address, then you use the dereference operator *.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Sep 2009
    Location
    San Antonio, TX
    Posts
    9
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    int sreplace(char newc, char oldc, char *s){
    	int numReplaced = 0;
    	while (*s != '\0'){
    		if (*s == oldc){
    			*s = newc;
    			numReplaced++;
    		}
    		s++;
    	}
    	
    
    
    
    	return numReplaced;
    	// return number of replacements made
    }

    i think i understood what you were saying but now i get no output lol
    Last edited by cubis; 09-25-2009 at 03:37 PM.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Why does the description of your program break its own rules?
    The functions are to only use pointers, there should be no arrays in any of the functions. You will, of course, need to define a character array in which to read the input in your main driver program.
    Now, if it were me, and they gave me those rules, I'd do this:
    Code:
    int sreplace(char newc, char oldc, char *s)
    {
        size_t x = 0;
        int numReplaced = 0;
    
        while( s[ x ] )
        {
            if( s[ x ] == oldc )
            {
                s[ x ] = newc;
                numReplaced++;
            }
            x++;
        }
    
        return numReplaced;
    	return numReplaced;
    	// return number of replacements made
    }
    Then I'd argue that I didn't actually use any arrays, because I'd use malloc in main, and point out that any time an array is passed to a function, it's actually passed as a pointer to the type of the first element. I'd win too, especially when I pointed out that the description of the problem breaks its own rule.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by quzah View Post
    Why does the description of your program break its own rules?Now, if it were me, and they gave me those rules, I'd do this:
    Code:
    int sreplace(char newc, char oldc, char *s)
    {
        size_t x = 0;
        int numReplaced = 0;
    
        while( s[ x ] )
        {
            if( s[ x ] == oldc )
            {
                s[ x ] = newc;
                numReplaced++;
            }
            x++;
        }
    
        return numReplaced;
        return numReplaced;
        // return number of replacements made
    }
    Then I'd argue that I didn't actually use any arrays, because I'd use malloc in main, and point out that any time an array is passed to a function, it's actually passed as a pointer to the type of the first element. I'd win too, especially when I pointed out that the description of the problem breaks its own rule.


    Quzah.
    I agree. In this context, index notation is just shorthand for 'add, then dereference'.

    @cubis:

    Code:
    int sreplace(char newc, char oldc, char *s) {
        int i, numReplaced = 0;
        for (i = 0; i[ s ]; i++){
            if (i[ s ] == oldc){
                i[ s ] = newc;
                numReplaced++;
            }
        }
    }
    I don't see any arrays there, do you?

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Oh that's even a better way to do it! I always forget about that one. It's great.


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Sep 2009
    Location
    San Antonio, TX
    Posts
    9
    lol



    well i dunno about what all that means but i'm sure he didn't count the main driver as a function. i used 2 character arrays in driver.c


    could you explain why those also work? you guys just owned me with your skillz haha

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by cubis View Post
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    int sreplace(char newc, char oldc, char *s){
    	int numReplaced = 0;
    	while (*s != '\0'){
    		if (*s == oldc){
    			*s = newc;
    			numReplaced++;
    		}
    		s++;
    	}
    	return numReplaced;
    	// return number of replacements made
    }
    i think i understood what you were saying but now i get no output lol
    Actually now that function is completely correct. Well done! You certainly do get output, it's probably just that you're looking at s before the return instead of looking at the string after the program has returned to the calling function. Besides, a function that returns something cant give no output in C. Show what you mean.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Registered User
    Join Date
    Sep 2009
    Location
    San Antonio, TX
    Posts
    9
    sorry about not being clear

    this is my driver:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int sreplace(char newc, char oldc, char *s);
    char *strmatch(char *str, char *s);
    
    int main(void)
    {
    	
    // maxline is 1024 including '\n'
    char lineA[1026];
    char lineB[1026];
    
    lineA[1025] = 'x';
    lineB[1025] = 'x';
    /* just need anything to fill it up, null 
       terminator goes there if array is full */
    int i = 0;
    int k = 0;
    int j = 0;
    	while ((fgets(lineA, 1026, stdin) != NULL))
    	{
    		if (fgets(lineB, 1026, stdin) != NULL){
    			
    			if ( (lineA[1025] == '\0') || (lineB[1025] == '\0'))
    			{
    				fprintf(stderr, "Error: line exceeds 1023 characters\n");
    				exit(-1);
    			}
    			
    			sreplace('3', 'e', lineA);
    			sreplace('3', 'e', lineB);
    
    			for (i=0; lineA[i] != '\n'; i++){
    				printf("%c", lineA[i]);
    			}
    			printf("\n");
    
    			for (k=0; lineB[k] != '\n'; k++){
    				printf("%c", lineB[k]);
    			}
    			printf("\n");
    		}
    		else {
    			if (lineA[1025] == '\0'){
    				fprintf(stderr, "Error: line exceeds 1023 characters\n");
    				exit(-1);
    			}
    			sreplace('3', 'e', lineA);
    
    			
    			for (j=0; lineA[j] != '\n'; j++){
    				printf("%c", lineA[j]);
    			}
    			printf("\n");
    		
    		}
    
    	}
    
    
    	exit(0);
    }

    when i compile and run data.in (just random words that contain the letter e) into it and output it to data.out, data.out is empty

  13. #13
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> if (fgets(lineB, 1026, stdin) != NULL){

    You should avoid using hard-coded constants.

    Code:
    const size_t BUFFERSIZE = 1025;
    // ...later... 
    if (fgets(lineB, BUFFERSIZE, stdin) != NULL)
    >> if ( (lineA[1025] == '\0') || (lineB[1025] == '\0'))

    That isn't correct, really. Use strlen.

    >> for (i=0; lineA[i] != '\n'; i++)

    That's not correct either. The newline might not even be present. You should be using '\0' instead, generally.

    At any rate, you didn't post the newest code for 'sreplace', so I'm assuming it hasn't changed, correct? If not, then your problem is probably I/O related (you really should have tested the function, to be sure).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with returning arrays using pointers
    By cuba06 in forum C Programming
    Replies: 9
    Last Post: 11-23-2007, 10:40 AM
  2. Array of Pointers to Arrays
    By Biozero in forum C Programming
    Replies: 2
    Last Post: 04-19-2007, 02:31 PM
  3. Pointers and multi dimensional arrays
    By andrea72 in forum C++ Programming
    Replies: 5
    Last Post: 01-23-2007, 04:49 PM
  4. pointers and arrays..
    By ahming in forum C Programming
    Replies: 1
    Last Post: 04-24-2004, 03:12 AM
  5. Stack functions as arrays instead of node pointers
    By sballew in forum C Programming
    Replies: 8
    Last Post: 12-04-2001, 11:13 AM