okay guys, plz help, this is so wierd. I am not an expert in C, in fact, not an expert in anything.

I defined a struct as the following:

typedef struct Fact
{
	char predicate[MAX_TOKEN_SIZE];
	struct Fact* valuePtr;
	struct Fact* next;
}Fact;

and i have some code like this, reading from a text file:

while(fgets(line, sizeof(line), inputFilePtr))
{
        charPtr = line;   
        i = 0;
        //buildStructure is a function that returns a Fact
        Fact lineFact = buildStructure(line);
        
        if(totalFact==0)
        {
            factsPtr = &lineFact;
        }
        //start of block A
        puts("oooooooo");
        puts((*((*factsPtr).valuePtr)).predicate);
        if(hasValue(*((*factsPtr).valuePtr))){puts("has value");}
        if(hasNext(*((*factsPtr).valuePtr))){puts("has next");}
        puts("oooooooo");
        //end of block A
        totalFact++;
}
        //block B, this block of code is the exact same copy of block A
        puts("oooooooo");
        puts((*((*factsPtr).valuePtr)).predicate);
        if(hasValue(*((*factsPtr).valuePtr))){puts("has value");}
        if(hasNext(*((*factsPtr).valuePtr))){puts("has next");}
        puts("oooooooo");
.....

int hasNext(Fact f)
{
    if(f.next!=NULL)
    {
        return TRUE;
    }
    return FALSE;
}

int hasValue(Fact f)
{
    if(f.valuePtr!=NULL)
    {
        return TRUE;
    }
    return FALSE;
}

Although block B is the exact same copy of block A, their output is different:
block A gives:
oooooooo
tom
oooooooo

and block B gives:
oooooooo
tom
has value
has next
oooooooo

I just dont get it, because I think i didn't change anything after block A, but block B's output is different. My input text file has only one line and it seems after the while loop, the pointers in my struct suddenly points to something, while in the the while loop, it points to nothing. please give me some suggestions, THANK YOU!!!!

Recommended Answers

All 7 Replies

we don't have enough of the code to tell you what is wrong.

lines 14, 15 and 16: you are making that much more difficult than it needs to be. puts(factsPtr->valuePtr->predicate); But without the rest of the code I can't be certain the above is actually correct. In any event it looks a lot simpler and clearer.

Lemme guess, block B is outside your while loop.

And since you didn't post the declaration of factsPtr, I'm guessing that's before the loop as well (otherwise it wouldn't compile)

> factsPtr = &lineFact;
Now here's the rub. When the loop exits, lineFact goes out of scope (it's localised to the while loop). But you have a sneaky pointer to it. Dereferencing that pointer after the loop exits gets you JUNK data (despite the apparent 'success' of the first field).

okay, I have come to the conclusion that C just sucks!!!!
I did this program with java in like 2 days... and I just can't figure out WTF is wrong with it... thank you guys. C just sucks!!!!

>C just sucks!!!!
Correction. You suck at C.
Post the complete pertaining code.

this is my hw, i have to read the text file and create a logical structure representing the facts(whatever u call it)and print it out in a out put file, all i am doing now is trying to print it in console...

#include<stdio.h>
#include<string.h>
#include<errno.h>

#define FALSE 0
#define TRUE 1
#define MAX_LINE_SIZE 257
#define MAX_FILENAME_SIZE 21
#define MAX_TOKEN_SIZE 31

typedef struct Fact
{
	//char *predicate; 
	char predicate[MAX_TOKEN_SIZE];
	struct Fact* valuePtr;
	struct Fact* next;
}Fact;

Fact buildStructure(char* line);
void sortFacts();
void writeToFile();
int notADelimitor(char c);
char* getFactString(Fact *factPtr);

int lineEnds = FALSE;
char *charPtr;
int started = TRUE;
int ended = FALSE;
int i;
int totalFact = 0;
Fact *factsPtr;
char token[MAX_TOKEN_SIZE];

int main()
{
	FILE *inputFilePtr;
	char inputFileName[MAX_FILENAME_SIZE];
	char outputFileName[MAX_FILENAME_SIZE];
	char line[MAX_LINE_SIZE];
	int readingFromStart = FALSE;

	printf("Input File Name: ");
	gets(inputFileName);
	printf("Output File Name: ");
	gets(outputFileName);

	if((inputFilePtr=fopen("input.txt", "r"))==NULL)
                {
		printf("cannot open file");
		printf("\npress ENTER to exit this program");
		char key[5];
		gets(key);
		exit(1);
	}
	
	while(fgets(line, sizeof(line), inputFilePtr))
                {
		charPtr = line;
                                i = 0;

                                Fact lineFact = buildStructure(line);
        
                                if(totalFact==0)
                               {
                                            factsPtr = &lineFact;
                               }
                               puts((*((*factsPtr).valuePtr)).predicate);
	           if(hasValue((*((*factsPtr).valuePtr)).predicate))
                                     {puts("has value");}
	           if(hasNext((*((*factsPtr).valuePtr)).predicate))
                                     {puts("has next");}
                          totalFact++;
	}
	puts((*((*factsPtr).valuePtr)).predicate);
	           if(hasValue((*((*factsPtr).valuePtr)).predicate))
                                     {puts("has value");}
	           if(hasNext((*((*factsPtr).valuePtr)).predicate))
                                     {puts("has next");}
                          totalFact++;
	writeToFile();
	
	printf("\npress ENTER to exit this program");
	char key[5];
	gets(key);

	exit(0);
	
}

Fact buildStructure(char *line)
{
	Fact thisFact;

	if(!lineEnds)
                {
        if(charPtr[i]==46)        {  
                       lineEnds = TRUE;         
        }
        else
        {   
            if(charPtr[i]==' ')
            {
                i++;
            } 
            if(notADelimitor(charPtr[i]))
            {
                int j = 0;
                while(notADelimitor(charPtr[i]))
                {
                    token[j] = charPtr[i];
                    i++;
                    j++;
                }
                token[j]=0;//
                thisFact = buildStructure(line
            }
            
            else if(charPtr[i]==',')
            {
                i++;
                if(!ended)
                {
                    strcpy(thisFact.predicate, token);
                    thisFact.valuePtr = NULL;
                }
            }
            else if(charPtr[i]==')' && !ended)
            {
                i++;
                if(!ended)
                {
                    ended = TRUE;
                }
                strcpy(thisFact.predicate, token);

                thisFact.next = NULL;
                thisFact.valuePtr = NULL;

            }
            else if(charPtr[i]=='(')
            {
                i++;
                started = TRUE;
                int k = 0;
                Fact* valueCursor;
                
                strcpy(thisFact.predicate, token);
                
                while(!ended)
                {

                    if(k==0)
                    {

                        Fact valueFact = buildStructure(line);//2

                        thisFact.valuePtr = &valueFact;
                        puts(valueFact.predicate);
                        if(valueFact.valuePtr==NULL){puts("no value");}

                        valueCursor = thisFact.valuePtr;
                        thisFact.next = NULL;
                        k++;
                    }
                    else
                    {

                        Fact valueFact = buildStructure(line);

                        (*valueCursor).next = &valueFact;
                        valueCursor = &valueFact;
                        if(ended)
                        {
                            valueFact.next = NULL;
                        }
                        
                    }

                }
            }
        }
    }
    
    return thisFact;
}

void sortFacts()
{
     
}

void writeToFile()
{
    Fact f = (*factsPtr);
    int i;

    for(i = 0; i < totalFact; i++)
    {
        char* string = NULL;
        printf("%s", getFactString(factsPtr));
        factsPtr = f.next;
    }
}

char* getFactString(Fact* factPtr)
{
    if(factPtr==NULL)
    {
        return NULL;
    }
    else
    {
        

        Fact f = *factPtr;


        
        char* string = f.predicate;

        puts(string);
        
        if(hasValue(f))
        {
            puts(f.predicate);
            puts("has value");
            strcat(string, "(");
            char* valueFactString = getFactString(f.valuePtr);
            strcat(string, valueFactString);
            strcat(string, ")");
        }
        if(hasNext(f))
        {
            puts(f.predicate);
            puts("has next");
            strcat(string, ", ");
            char* nextFactString = getFactString(f.next);
            strcat(string, nextFactString);
            strcat(string, ")");
        }
        puts(string);
        return string;
    }
}

int notADelimitor(char c)
{
    if(c!='('&&c!=','&&c!=' '&&c!=')')
    {
        return TRUE;
    }
    return FALSE;
}

int hasNext(Fact f)
{
    if(f.next!=NULL)
    {
        return TRUE;
    }
    return FALSE;
}

int hasValue(Fact f)
{
    if(f.valuePtr!=NULL)
    {
        return TRUE;
    }
    return FALSE;
}

okay, this is the whole thing, there's lots of redundant things in there, I sincerely thank anyone who will even look at it. Its so hard to find any info on C in the internet.... handling string in C is a pain!!!! GOD, I still think C sucks, it's more efficient, but it makes people go MAD!!!!

by the way, this is all that is in my text file:
enrolled(tom).

yeah, the last character is a return.

basically, all i want know is to know why the two block of code exactly the same above the writeToFile method prints different stuff, one block is in the while loop while the other is outside of the loop, plz ignore the writeTofile method, that's another dosage of pain...

There's a ton of info on C, have you tried Google? And C seems more difficult because it doesn't do everything for you, like Java will. Lots of people prefer this greater control over their applications. Plus, it makes it much faster.

I gave an answer (to the immediate problem anyway), then lost interest when the toys were being thrown out of the pram.

FWIW, it might take you a month to learn enough C to make a half-decent job of this assignment. But if you're going to whine about it after 2 days then you really don't have the temperament to be a C programmer. Frustration and confusion are in the job description, get used to it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.