Thread: gcc compile errors, HELP!

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    4

    gcc compile errors, HELP!

    Hello,

    I'm new to C programming, taking a course in college on System Architecture. Anyways, I'm required to submit a project, and I have to build it using gcc -ansi. When I run the following command:

    gcc wordstat.c -ansi wordstat

    it generates the following output:

    wordstat.c: In function `main':
    wordstat.c:316: parse error before `char'
    wordstat.c:317: `newline' undeclared (first use in this function)
    wordstat.c:317: (Each undeclared identifier is reported only once
    wordstat.c:317: for each function it appears in.)
    wordstat.c:329: parse error before `*'
    wordstat.c:333: `dictionaryHead' undeclared (first use in this function)
    wordstat.c:334: `textHead' undeclared (first use in this function)
    wordstat.c:337: `pointer' undeclared (first use in this function)
    wordstat.c: In function `checkArgument':
    wordstat.c:382: parse error before `*'
    wordstat.c:383: `fp' undeclared (first use in this function)


    My code looks fine to me, I don't understand why I'm getting these errors. Thank you so much for your help! Below here I've included the contents of the files being compiled.


    The files being used are wordstat.c and wordstat.h. Here are there contents:


    WORDSTAT.C file:
    Code:
    /* wordstat.c : Defines the entry point for the console application.*/
    
    #include "wordstat.h"
    
    /*inserts a new node with data = nodeData to the head of the list*/
    void insertBeginning(WORD **listHead, char nodeData[100])
    {
    	WORD *temp;
    	if(*listHead == NULL) /*no head, create a new word and make listHead point to it*/
    	{
    		temp = (WORD *)malloc(sizeof(WORD));
    		strcpy(temp->data, nodeData);
    		temp->nextNode = NULL;
    		*listHead = temp;
    	}
    	else /*make a new word, point its next to head, and then point listHead to the new word*/
    	{
    		temp = (WORD *)malloc(sizeof(WORD));
    		strcpy(temp->data, nodeData);
    		temp->nextNode = *listHead;
    		*listHead = temp;
    	}
    }
    
    /*This function takes two char* arrays, compares there characters one at a time until a difference is found and returns the result*/
    int compareWords(char *word1, char *word2)
    {
    	char word1Char;
    	char word2Char;
    	int counter = 0;
    	int returnValue; /*if < 0, wta is smaller, if > 0 wta is larger, if = 0 the words are the same*/
    
    	word1Char = word1[counter];
    	word2Char = word2[counter];
    
    	while(word1Char != 0 || word2Char != 0)/*loop over the arrays looking for a difference, stop if we hit the end of a word*/
    	{
    		returnValue = word1Char - word2Char;
    
    		if(returnValue != 0)
    		{
    			return returnValue; /*we've found a difference, so lets return it*/
    		}
    
    		/*no difference so increment our counter and set the next characters to examine*/
    		counter++;
    		word1Char = word1[counter];
    		word2Char = word2[counter];
    	}
    
    	/*if we reach here, then one of the values is null, so we need to handle what to return*/
    	returnValue = word1Char - word2Char;
    
    	return returnValue;
    }
    
    /*search for the word in the dictionary.  If it is found, return 1, else return 0*/
    void checkDictionary(WORD *word, WORD *dictionaryHead)
    {
    	int comparisonValue;
    	WORD *pointer = dictionaryHead;
    	
    	while(pointer != NULL) /*loop over the list*/
    	{
    		comparisonValue = compareWords(word->data, pointer->data); /*see if the word matches a word in dictionary*/
    		if(comparisonValue == 0)/* we have a match*/
    		{
    			word->inDictionary = 1; /*set the flag that shows the word was in the dictionary*/
    			return;
    		}
    
    		pointer = pointer->nextNode;
    	}
    
    	/*if we reach this point, then the word was not found in the dictionary*/
    	word->inDictionary = 0;
    	return;
    }
    
    
    
    
    /*inserts a new word into the linked list sorting by the data value.  If word matches another word, increments the count instead of adding*/
    WORD* insertSort(WORD **listHead, WORD **wordToAdd)
    {
    	WORD *previous;
    	WORD *current = *listHead;
    	WORD *word = *wordToAdd;
    	int loopCounter = 0; /*needed to make sure we don't access previous if previous isn't set*/
    	int difference = 0;
    	
    	while(current != NULL) /*we haven't reached the end of the list yet, keep looping*/
    	{
    		if(loopCounter == 0)
    		{
    			difference = compareWords(word->data, current->data);
    			if(difference < 0) /*word comes before current*/
    			{
    				word->nextNode = current;
    				return word;
    			}
    			else if(difference > 0) /*word comes after current, advance pointer*/
    			{
    				previous = current;
    				current = current->nextNode;
    			}
    			else /*word is the same as current*/
    			{
    				current->count = current->count + word->count;
    				free(word);
    				return *listHead;
    			}			
    		}
    		else /*using previous is fine*/
    		{
    			difference = compareWords(word->data, current->data);
    			if(difference < 0) /*word comes before current*/
    			{
    				previous->nextNode = word;
    				word->nextNode = current;
    				return *listHead;
    			}
    			else if(difference > 0) /*word comes after current, advance pointer*/
    			{
    				previous = current;
    				current = current->nextNode;
    			}
    			else /*word is the same as current*/
    			{
    				current->count = current->count + word->count;
    				free(word);
    				return *listHead;
    			}	
    		}
    
    		loopCounter++;
    	}
    
    	/*if we reach here, then the word goes on the end of the list*/
    	previous->nextNode = word;
    	word->nextNode = NULL;
    
    	return *listHead;
    }
    
    /*take the head of a list and print all of the words in the list, with collums for word, count and inDictionary*/
    void printWordList(WORD *listHead) 
    {
    	WORD *pointer;
    	pointer = listHead;
    	printf("\nWORDS\t\t\tFREQUENCIES\t\tIN DICTIONARY?\n");
    
    	while(pointer != NULL)
    	{
    		printf(pointer->data);
    		printf("\t\t\t");
    		printf("%i", pointer->count);
    		printf("\t\t\t");
    		if(pointer->inDictionary == 1)
    		{
    			printf("Y\n");
    		}
    		else
    		{
    			printf("N\n");
    		}
    
    		pointer = pointer->nextNode;
    	}
    }
    
    
    /*this function takes no parameters, reads the dict.txt file, creates a linked list of all the words in the dict.txt file, 
    and returns a pointer to the head of the list.  This function is better for reading the dictionary than readText() because
    we can grab the whole line at once (based on the formatting of the dictionary file), so we don't have to read one character
    at a time.*/
    WORD* readDictionary()
    {
    	/*declare local variables*/
    	WORD *headPtr;
    	WORD *current;
    	int wordCount = 0;
    	char readBuffer[100];
    
    	FILE *fp = fopen("dict.txt", "rb"); /*open the dict.txt file*/
    
    	if(fp == NULL)/*if the file failed to open, print out warning message and return headPtr*/
    	{
    		printf("Failed to open dict.txt.  Please make sure the dictionary file is present.");
    		return headPtr;
    	}
    
    	while(fgets(readBuffer, 99, fp) != NULL) /*while loop to read each line of the dictionary file*/
    	{
    		int bufferCounter = 0;
    		char bufferChar = readBuffer[bufferCounter];
    
    		/*we need to find the end of the word in the buffer, so we can set the following character to 0*/
    		while(bufferChar > 64 && bufferChar < 91) /*this is a character I want to keep*/
    		{
    			bufferCounter++;
    			bufferChar = readBuffer[bufferCounter];
    		}
    		readBuffer[bufferCounter] = 0; /*need to set character after last letter = 0*/
    
    		/*if we're creating the first word in the dictionary, we'll just handle that here.  Else use insertBeginning*/
    		if(wordCount == 0)
    		{
    			headPtr = (WORD *)malloc(sizeof(WORD));
    			strcpy(headPtr->data, readBuffer);
    			headPtr->nextNode = NULL;
    		}
    		else
    		{
    			insertBeginning(&headPtr, readBuffer);
    		}
    		wordCount++;
    	}
    
    	fclose(fp);
    
    	return headPtr;
    }
    
    /*reads the given text file, creates a linked list of WORD, and returns pointer to head of the linked list*/
    WORD* readText(char *fileName)
    {
    	/*declare local variables*/
    	char *readBuffer = (char*)malloc(sizeof(char[100]));
    	char readCharacter;
    	int wordCounter = 0;
    	int characterCounter = 0;
    	WORD* textHead;
    	WORD* newWord;
    	FILE *fp = fopen(fileName, "rb");
    
    	readCharacter = getc(fp);
    	while(readCharacter != EOF)
    	{
    		if(readCharacter > 64 && readCharacter < 91) /*character is a capital alphabetic character, and should be added to read buffer*/
    		{
    			readBuffer[characterCounter] = readCharacter;
    			characterCounter++;
    		}
    		else if(readCharacter > 96 && readCharacter < 123) /*character is a lowercase alphabetic character and should be converted to upper and added to read buffer*/
    		{
    			readBuffer[characterCounter] = readCharacter - 32;
    			characterCounter++;
    		}
    		else if (characterCounter > 0) /*we have read in a non alphabetic character with alphabetic characters in the readBuffer.  We have reached the end of a word.  Add the word to the words array.*/
    		{
    			if(wordCounter == 0)/*this is our first word*/
    			{
    				readBuffer[characterCounter] = 0;
    				textHead = (WORD*)malloc(sizeof(WORD));
    				strcpy(textHead->data, readBuffer);
    				textHead->nextNode = NULL;
    				textHead->count = 1;
    				textHead->inDictionary = 0;
    			}
    			else /*this is a new word, needs to be inserted into our linked list*/
    			{
    				readBuffer[characterCounter] = 0;
    				newWord = (WORD*)malloc(sizeof(WORD));
    				strcpy(newWord->data, readBuffer);
    				newWord->nextNode = NULL;
    				newWord->count = 1;
    				newWord->inDictionary = 0;
    				textHead = insertSort(&textHead, &newWord);
    			}
    
    			/*reset our buffer and increment our wordCounter*/
    			free(readBuffer);
    			readBuffer = (char*)malloc(sizeof(char[100]));
    			characterCounter = 0;
    			wordCounter++;
    		}
    		/*if we reached none of these ifs, we have read in a non alphabetic with no alphabetic characters in the readBuffer, so do nothing and move on to next character*/
    
    		/*read the next character*/
    		readCharacter = getc(fp);
    	}
    
    	/*we've reached EOF.  Close file and return.	*/
    	fclose(fp);
    	return textHead;
    }
    
    
    int main(int argc, char *argv[])
    {
    	char inputBuffer[100]; /*for reading input from user if original arguments are invalid*/
    	int sentry = 1; /*used to make sure we don't advance until the arguments are valid*/
    	if(argc < 2) /*we have too few arguments*/
    	{
    		sentry = 1; /*sentry != 0 means we have a problem with the arguments*/
    	}
    	else if(argc == 2) /*lets check and see if our arguments are valid*/
    	{
    		sentry = checkArgument(argv[1]);
    	}
    	else /*we have too many arguments*/
    	{
    		sentry = 1;
    	}
    
    	if(sentry == 0) /*our arguments are good, lets copy them to inputBuffer for use*/
    	{
    		strcpy(inputBuffer, argv[1]);
    	}
    
    	while(sentry != 0) /*our arguments were bad, so lets get the user to give proper input*/
    	{
    		printf("Please enter the filename for the text file to process, or enter -h for help.  Press Enter to exit: ");
    		fgets( inputBuffer, sizeof(inputBuffer), stdin);
    		char *newline = strchr(inputBuffer, '\n');
    		if(newline != NULL)
    		{
    			*newline = '\0';
    		}
    		sentry = checkArgument(inputBuffer);
    		if(sentry == -1)/*user entered '0', so they wish to exit.*/
    		{
    			return 0;
    		}
    	}
    
    	/*ok, we're done checking for valid arguments, we have one, lets process!*/
    	WORD *dictionaryHead;
    	WORD *textHead;
    	WORD *pointer;
    
    	dictionaryHead = readDictionary(); /*read the dictionary into a linked list of words*/
    	textHead = readText(inputBuffer); /*read the text file into a linked list of words*/
    
    	/*check if each word from the text is in the dictionary, and set its inDictionary value accordingly*/
    	pointer = textHead;
    	while(pointer != NULL)
    	{
    		checkDictionary(pointer, dictionaryHead);
    		pointer = pointer->nextNode;
    	}
    
    	printWordList(textHead); /*print our output*/
    
    	/*time to free all the stuff we dynamically allocated*/
    	while(dictionaryHead != NULL)
    	{
    		WORD *freePointer = dictionaryHead;
    		dictionaryHead = dictionaryHead->nextNode;
    		free(freePointer);
    	}
    	
    	while(textHead != NULL)
    	{
    		WORD *freePointer = textHead;
    		textHead = textHead->nextNode;
    		free(freePointer);
    	}
    
    	return 0;
    }
    
    /*this function will check if our arguments were valid.  If so, returns 0.  If user wants to exit returns -1.  Else returns 1.*/
    int checkArgument(char *arg)
    {
    	if(arg[0] == 0) /*the user wants to exit.*/
    	{
    		return -1;
    	}
    
    	if(arg[0] == 45 && arg[1] == 104) /*we have a -h, lets check to make sure that is -h by itself, and if it is, print out the help string.*/
    	{
    		if(arg[2] == 0)
    		{
    			printf("\nwordstat.exe is an executable that will take in a single argument, which is a file name to a text document.  When given a valid filename, wordstat will read the text file, compare it against the dictionary in dict.txt, and print out the words in alphabetical order, with frequency and whether the word is in the dictionary.\n\n");
    		}
    		return 1; /*we're not done getting input from user*/
    	}
    
    	/*if we got here then input wasn't 0 and wasn't -h, so we check to see if we can open the file*/
    	FILE *fp = fopen(arg, "rb");
    	if(fp == NULL) /*we couldn't open the file*/
    	{
    		printf("\nError opening the indicated file.\n\n");
    		return 1;
    	}
    	fclose(fp); /*we could open the file.  So close it for now, and return 0 to prepare for processing*/
    
    	return 0;
    }
    WORDSTAT.H file:
    Code:
    /* wordstat.h : include file for standard system include files,
     or project specific include files that are used frequently, but
     are changed infrequently*/
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct word
    {
    	int count; /*how many times was this word in the document*/
    	int inDictionary; /*0 for NO, 1 for YES*/
    	char data[100]; /*string holding the word*/
    	struct word *nextNode; /*pointer to next word in the linked list*/
    }
    WORD;
    
    int checkArgument(char *arg);

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Those error messages are very explicit, even giving you the line numbers...
    Check them out one at a time and find out what the compiler doesn't like.

    A "parse error" could well occur above main but not be triggered until you enter main... in this case I'd check the pairing of my braces and brackets.

    It's also showing several variables that are undeclared before use... that's very easy to fix.

    The CheckArgument function should probably be above main in your source code.

    The header file should use an "include guard" (Google is your friend)

    And it's not how your code looks to you... it's how it looks to the compiler. Error messages are very helpful in this regard.

  3. #3
    Registered User
    Join Date
    Aug 2006
    Posts
    12
    Code:
    	{
    		printf("Please enter the filename for the text file to process, or enter -h for help.  Press Enter to exit: ");
    		fgets( inputBuffer, sizeof(inputBuffer), stdin);
    		char *newline = strchr(inputBuffer, '\n');   /* <-- not allowed in C90 */
    		if(newline != NULL)
    		{
    You are not allowed to declare new variables 'inline' according to the C90 standard. This is a feature that was invented later (with C++). More liberal compilers (such as gcc) will let you get away with it, similar to allowing // for comments. If you are more strict (by using -ansi and/or -pedantic) the compiler won't allow it.

    LT.
    Last edited by Lord Thunder; 02-13-2011 at 11:35 AM. Reason: Rewording.

  4. #4
    Registered User
    Join Date
    Feb 2011
    Posts
    4
    Quote Originally Posted by CommonTater View Post
    Those error messages are very explicit, even giving you the line numbers...
    Check them out one at a time and find out what the compiler doesn't like.

    A "parse error" could well occur above main but not be triggered until you enter main... in this case I'd check the pairing of my braces and brackets.

    It's also showing several variables that are undeclared before use... that's very easy to fix.

    The CheckArgument function should probably be above main in your source code.

    The header file should use an "include guard" (Google is your friend)

    And it's not how your code looks to you... it's how it looks to the compiler. Error messages are very helpful in this regard.
    CommonTater,

    Thank you for your response. I've checked every brace and bracket trying to find the parse error, and I can't find one. I've even used a search to tell me how many I have of each (open and closee) and I have matching numbers.

    I thought that since checkArgument is prototyped in the header file, I shouldn't need to put it before main. Is this incorrect?

    As for the undeclared variables, I don't understand how that is the case, they are declared and then used here:

    Code:
    	/*ok, we're done checking for valid arguments, we have one, lets process!*/
    	WORD *dictionaryHead;
    	WORD *textHead;
    	WORD *pointer;
    
    	dictionaryHead = readDictionary(); /*read the dictionary into a linked list of words*/
    	textHead = readText(inputBuffer); /*read the text file into a linked list of words*/
    Thank you so much for your feedback!

  5. #5
    Registered User
    Join Date
    Feb 2011
    Posts
    4
    Quote Originally Posted by Lord Thunder View Post
    Code:
    	{
    		printf("Please enter the filename for the text file to process, or enter -h for help.  Press Enter to exit: ");
    		fgets( inputBuffer, sizeof(inputBuffer), stdin);
    		char *newline = strchr(inputBuffer, '\n');   /* <-- not allowed in C90 */
    		if(newline != NULL)
    		{
    You are not allowed to declare new variables 'inline' according to the C90 standard. This is a feature that was invented later (with C++). More liberal compilers (such as gcc) will let you get away with it, similar to allowing // for comments. If you are more strict (by using -ansi and/or -pedantic) the compiler won't allow it.

    LT.
    By 'inline' do you mean that I should instead be doing:

    Code:
    char *newline;
    newline = ...
    Or do you mean that the declaration needs to come outside of the loop I'm in? such as:

    Code:
    char *newline;
            while(sentry != 0) /*our arguments were bad, so lets get the user to give proper input*/
    	{
    		printf("Please enter the filename for the text file to process, or enter -h for help.  Press Enter to exit: ");
    		fgets( inputBuffer, sizeof(inputBuffer), stdin);
    		newline = strchr(inputBuffer, '\n');
    		if(newline != NULL)
    		{
    			*newline = '\0';
    		}
    		sentry = checkArgument(inputBuffer);
    		if(sentry == -1)/*user entered '0', so they wish to exit.*/
    		{
    			return 0;
    		}
    	}
    Also, can you see why the declarations for dictionaryHead, textHead and pointer aren't working? Thank you very much for your feedback!

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ok... a parse error (in most compilers) means the compiler has reached some point where it can no longer keep track of what's going on... Kinda like you losing your place in a book....

    These nasties can be caused by almost anything... A header file without a blank line at the end. A missing semicolon (although that usually also causes syntax errors) an un-matched brace, bracket, quote (single or double), comment, etc.

    This is why I suggested you add include guards on your header file...
    Code:
    #ifndef MY_INCLUDE
    #define MY_INCLUDE
    
    // content of header
    
    #endif // MY_INCLUDE
    This effectively eliminates half of the problem for you and it prevents the include file from being included multiple times.

    Of course you will edit "MY_INCLUDE" to be the name of the include file... WORDSTAT_H ... in this case.

    For the function beging above main... Two reasons... 1) Consistency... if you have stuff scattered all over the place It gets a little hard to find. 2) What if you decide not to use it in the header file?
    Last edited by CommonTater; 02-13-2011 at 11:56 AM.

  7. #7
    Registered User
    Join Date
    Feb 2011
    Posts
    4
    Quote Originally Posted by Lord Thunder View Post
    Code:
    	{
    		printf("Please enter the filename for the text file to process, or enter -h for help.  Press Enter to exit: ");
    		fgets( inputBuffer, sizeof(inputBuffer), stdin);
    		char *newline = strchr(inputBuffer, '\n');   /* <-- not allowed in C90 */
    		if(newline != NULL)
    		{
    You are not allowed to declare new variables 'inline' according to the C90 standard. This is a feature that was invented later (with C++). More liberal compilers (such as gcc) will let you get away with it, similar to allowing // for comments. If you are more strict (by using -ansi and/or -pedantic) the compiler won't allow it.

    LT.
    LT,

    By moving all of the declarations to the top of their respective functions these problems vanished. Thank you VERY MUCH. I was getting massively frustrated by this.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by FalconGK81
    By moving all of the declarations to the top of their respective functions these problems vanished.
    You actually only need to move them to the top of the innermost block in which they are used, e.g.,
    Code:
    while(sentry != 0) /*our arguments were bad, so lets get the user to give proper input*/
    {
        char *newline;
        printf("Please enter the filename for the text file to process, or enter -h for help.  Press Enter to exit: ");
        fgets( inputBuffer, sizeof(inputBuffer), stdin);
        newline = strchr(inputBuffer, '\n');
        if(newline != NULL)
        {
            *newline = '\0';
        }
        sentry = checkArgument(inputBuffer);
        if(sentry == -1)/*user entered '0', so they wish to exit.*/
        {
            return 0;
        }
    }
    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

  9. #9
    Registered User
    Join Date
    Aug 2006
    Posts
    12
    Quote Originally Posted by laserlight View Post
    You actually only need to move them to the top of the innermost block in which they are used, e.g., ...
    This is true, but then you also have to remember that you are not allowed to use that variable anywhere outside that block. (I cannot think of a sane piece of code where that would be a problem, but I am just saying )

    LT.
    Last edited by Lord Thunder; 02-13-2011 at 12:17 PM. Reason: Grammar :/

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Or, you could use a command line of

    Code:
    gcc wordstat.c --std=c99 wordstat

  11. #11
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by FalconGK81 View Post
    gcc wordstat.c -ansi wordstat
    While you are at it, try using the -o switch. What you have done will not work.

    Code:
    gcc wordstat.c -ansi -o wordstat

  12. #12
    Registered User
    Join Date
    Aug 2006
    Posts
    12
    Quote Originally Posted by rags_to_riches View Post
    Or, you could use a command line of
    Code:
    gcc wordstat.c --std=c99 wordstat
    If you cared to read the initial post, it says his assignment requires him to compile with -ansi, which means his teacher wants them to write ANSI-C code only, not C99.

    LT

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling GNU MP
    By mattnp12 in forum C Programming
    Replies: 3
    Last Post: 06-23-2011, 03:58 PM
  2. GCC compile c program
    By aweida in forum C Programming
    Replies: 6
    Last Post: 10-01-2010, 11:27 AM
  3. Weird compile errors (gcc, pthread, math)
    By skytreader in forum C Programming
    Replies: 7
    Last Post: 07-20-2010, 11:33 AM
  4. multiple include of header file gives compile errors
    By jeanluca in forum C Programming
    Replies: 5
    Last Post: 04-16-2010, 02:36 PM
  5. Compile errors in stl header files
    By Swordsalot in forum C++ Programming
    Replies: 2
    Last Post: 07-20-2008, 02:41 AM