Thread: Header File Trouble... Again

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    26

    Header File Trouble... Again

    I know I've made multiple posts on this subject, but I can't seem to figure out how to compile multiple source files using header files. I read the FAQ and previous posts and I'm doing everything right I think, here's my code.

    MAIN CODE

    Code:
    #include "myString.h"
    
    int wordCount (const char text[]);
    void readLine(char buffer[]);
    
    int main(void) {
    	
    	bool endOfText = false;
    	char text[81];
    	int count = 0;
    	
    	while (!endOfText) { 
    		
          readLine(text);
    		
    		if (text[0] == '\0')
    			endOfText = true;
    		else
    			count += wordCount(text);
    	}
    	
    	printf("Number of words equals %i", count);
    	
    	return 0;
    }
    FUNCTION DECLARATION CODE

    Code:
    #include "myString.h"
    
    bool isNumericChar (const char c) {
    	
    	if ((c >= '0' && c <= '9') || c == ',' || c == '.' || c == '-')
    		return true;
    	else
    		return false;
    }
    
    bool isAlphaChar (const char c) {
    	
    	if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '\'')
    		return true;
    	else 
    		return false;
    }
    
    void readLine (char buffer[]) {
    	
    	char letter;
    	int i = 0;
    	
    	do {
    		 letter = getchar();
    		 buffer[i] = letter;
    		 i++;
    	} while (letter != '\n');
    	
    	buffer[i - 1] = '\0';
    }
    
    int wordCount (const char text[]) {
    	
    	bool lookForWord = true;
    	int count = 0, i;
    	
    	for (i = 0; text[i] != '\0'; i++) {
    		if (isAlphaChar(text[i]) || isNumericChar(text[i])) {
    			
    			if (lookForWord) {
    				count++;
    				lookForWord = false;
    			}
    		}
    		else 
    			lookForWord = true;
    	}
    			
    	return count;
    }
    
    bool isEqual (const char s1[], const char s2[]) {
    	
    	int i = 0;
    	
    	while (s1[i] == s2[i] && s1[i] != '\0')
    		i++;
    		
    		if (s1[i] == '\0' && s2[i] == '\0')
    			return true;
    		else 
    			return false;
    }
    
    void concat (char result[], const char s1[], const char s2[]) {
    	
    	int i = 0, j = 0;
    	
    	for (i = 0; s1[i] != '\0'; i++)
    		result[i] = s1[i];
    		
    	for (j = 0; s2[j] != '\0'; j++)
    		result[i + j] = s2[j];
    		
    	result[i + j] = '\0';
    }
    
    int compareTo (const char s1[], const char s2[]) {
    	
    	int i = 0;
    	
    	while (s1[i] == s2[i] && s1[i] != '\0')
    		i++;
    		
    	if (s1[i] < s2[i])
    		return -1;
    	else if (s1[i] == s2[i])
    		return 0;
    	else
    		return 1;
    	
    }
    
    int strToInt (const char s[]) {
    	
    	int intValue, result = 0, i;
    	
    	for (i = 0; s[i] >= '0' && s[i] <= '9'; i++) {
    		
    		intValue = 	s[i] - '0';
    		result = result * 10 + intValue;
    		
    	}
    	
    	return result;
    }
    HEADER FILE CODE

    Code:
    #include <stdio.h>
    #include <stdbool.h>
    
    #ifndef MYSTRING_H
    #define MYSTRING_H
    
    // functions
    bool isNumericChar (const char c);
    bool isAlphaChar (const char c);
    int wordCount (const char text[]);
    void readLine(char buffer[]);
    bool isEqual (const char s1[], const char s2[]);
    void concat (char result[], const char s1[], const char s2[]);
    int compareTo (const char s1[], const char s2[]);
    int strToInt (const char s[]);
    
    #endif
    I used jGRASP as my IDE and I put all these files into a project and I tried compiling the project, but it doesn't seem to compile the multiple source files. I tried to compile/link each individual file and I get the following error in main

    Code:
    text.c:1:
    myString.h:17:8: warning: no newline at end of file
    text.c:25:2: warning: no newline at end of file
    /cygdrive/c/DOCUME~1/jshowa/LOCALS~1/Temp/ccAGX7Qk.o: In function `main':
    text.c:14: undefined reference to `_readLine'
    text.c:19: undefined reference to `_wordCount'
    collect2: ld returned 1 exit status
    I also get segmentation fault errors when I try to compile the header file, but that's probably because I'm trying to compile a preprocessor file which isn't really compiled.

    I tried compiling it using the command line (gcc) and it worked, but I can't figure out why I can't use the IDE to do it.

    I looked in the help file under projects and I found this

    How To Compile a Program

    For languages such as Java with run-time linking, "Compiler" / "Compile" will compile the file, and in the case of Java, out-of-date dependencies (note that dependencies are compiled, not dependents). For languages such as C++ with build-time linking, "Compiler" / "Compile and Link" will create the executable for a single-file program, while "Compile" will compile the file only.[Interesting part]--> jGRASP does not provide a "build" function for multiple file programs in languages with build-time linking. For such programs, you should write a makefile or other build script.<-- For most jGRASP compiler environments, "Compiler" / "Make" will call the "make" command in the directory containing the file.

    So I tried making a make file and that made it work to, however I can't run the program in the IDE and it confuses me because I looked in two books on compiling and linking multiple source files, Programming in C and K&R and they tell me the exact same thing I'm doing! So I wonder how they did this back in the day before make existed.

    Anyways, if anyone can help me understand this or has any advice or comments that can help me clear this up, it would be of great help. Thank you.

    Oh and if there are any jGRASP users, please let me know if I'm doing this right.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If jGRASP does not provide a "build" function for multiple file programs in languages with build-time linking, then it looks like you can't use it for your purpose, since your purpose is multiple-file programs in a language with build-time linking.

    And make predates IDEs by ... oh, a lot.

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by jake123 View Post
    MAIN CODE

    Code:
    #include "myString.h" because of this
    
    int wordCount (const char text[]);don't need these lines
    void readLine(char buffer[]); //
    How are you compiling the program? What does your makefile look like?

  4. #4
    Registered User
    Join Date
    Feb 2008
    Posts
    26
    Quote Originally Posted by tabstop View Post
    If jGRASP does not provide a "build" function for multiple file programs in languages with build-time linking, then it looks like you can't use it for your purpose, since your purpose is multiple-file programs in a language with build-time linking.

    And make predates IDEs by ... oh, a lot.
    I know make predates IDE's, but I was just wondering how they did it back when the language was created. But I guess that's a stupid question because they probably just use the command line compiler.

    I was just wondering why I can't run the program in the IDE even though I can successfully build it using a makefile.

    Is there any IDE that you would suggest to use with build-time linking?

    Quote Originally Posted by robwhit View Post
    How are you compiling the program? What does your makefile look like?
    My makefiles fine and it works, I just can't run the program using the IDE so it makes it hard to debug it.

    Here's the make file.

    Code:
    SRC = text.c myString.c
    OBJ = text.o myString.o
    PROG = stringProject
    
    $(PROG): $(OBJ)
    			gcc $(OBJ) -o $(PROG)
    			
    $(OBJ): $(SRC)
    This code was mostly experimentation and I know that you don't need to declare the functions because of the header file declaration, I was just experimenting to see if I could get it to work.

    Since it's probably just an IDE issue, I really don't want to take up a lot of people's time since the help file basically answers the question. However, I wanted to test this because my friend is using IAR embedded workbench which has a build time linking function and I suggested this header file procedure to him and we couldn't get it to work.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by jake123 View Post
    I know make predates IDE's, but I was just wondering how they did it back when the language was created. But I guess that's a stupid question because they probably just use the command line compiler.

    I was just wondering why I can't run the program in the IDE even though I can successfully build it using a makefile.

    Is there any IDE that you would suggest to use with build-time linking?
    Honestly? Until this thread, I didn't know there were IDEs that didn't support build-time linking (at least one that claimed to support C/C++). So, pick an IDE (anjuta. geany. code::blocks. kdevelop. I forget whether nano has build support or if it's just an editor. gvim. And of course (shudder) emacs).

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    #include <stdio.h>
    Why do you need this in your header? there is nothing there that requires this dependency...

    It should be only included in main file
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    you're missing gcc $(SRC) -c -o $(OBJ)

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by robwhit View Post
    you're missing gcc $(SRC) -c -o $(OBJ)
    Not quite right. Since SRC contains two source files, I'd say the correct solution is one of these two [depending on preference]:
    Less explicit: just remove the whole $(OBJ): $(SRC) - there should be default rules to compile with
    Code:
    ${CC} ${CFLAGS} -o $@ $<
    Or be explicit:
    Code:
    CFLAGS = -Wall
    CC = gcc
    test.o: test.c
          ${CC} ${CFLAGS} -o $@ -c test.c
    
    myString.o: myString.c
          ${CC} ${CFLAGS} -o $@ -c myString.c

    To be complete, you may want this:
    Code:
    test.o: test.c myString.h
          ${CC} ${CFLAGS} -o $@ -c test.c
    
    myString.o: myString.c myString.h
          ${CC} ${CFLAGS} -o $@ -c myString.c
    This version means that make also takes into account whether myString.h has changed when building the object files - this should really be done.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Feb 2008
    Posts
    26
    Thanks for all the help robwhit, tabstop, matsp and vart, but I just switched to a new IDE that will let me tame this problem. Or I can just read the extensive make manual and try and teach myself make which would be fun.

    Thank you for the advice and assistance.

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by matsp View Post
    Not quite right.
    Right you are.

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by jake123 View Post
    I know make predates IDE's, but I was just wondering how they did it back when the language was created. But I guess that's a stupid question because they probably just use the command line compiler.
    I don't know for sure, but I would assume that after the first week of compiling by hand, make was invented. It's been around forever, basically. These days we have advanced features like autodep, but the basic idea of evaluating the changes in dependencies and re-running build steps is pretty much as old as UNIX.

    C was invented to write UNIX, and it certainly wasn't just "a few" source files!

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by brewbuck View Post
    C was invented to write UNIX
    ...which of course was created to port a game.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  2. Need help understanding Header Files
    By Kaidao in forum C++ Programming
    Replies: 11
    Last Post: 03-25-2008, 10:02 AM
  3. Header File Trouble
    By jake123 in forum C Programming
    Replies: 12
    Last Post: 03-07-2008, 05:10 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Replies: 6
    Last Post: 04-02-2002, 05:46 AM