-
Skipping the line.
I really hate to ask this, but I just can't stand this program any more. I have been working on it about 4-8 hours a day for last two or three days. And haven't made much progress. I am about to rip my hair out T-T But enough of that.
I want it to work like an address book, but get data from a file. When the program sees blank line, it should move on. But this function seems to be moving a line or two early. There are 4 lines (5 including the name that is copied into the function first). The loop will quit when it gets to the last line of the current company info, but the blank line gets put into the next companies name, and it shifts back from there. I tried adding an extra 'fgets' after the loop ended, but it didn't work. It seems to stop after picking up 4 lines, whether there are 5 lines or 4 in the company details.
I'll be back in a few. I am going to bash my head again a wall for a few minutes. Thanks in advance!
This is the function :
Code:
# include "lab05.h"
FILE *addLoop( struct entry **current, FILE ***fp, char name[]){
char buffer[ MAX ];
char buffer2[ MAX ];
char *str;
char *str2;
int i;
strcpy( (*current)->name, name );
i = 0;
while ( i<=4 && str!=NULL && !feof(**fp) ){
fgets( name, MAX, **fp );
strcpy( buffer, name);
strcpy( buffer2, buffer);
str = strtok( buffer, REMOVE);
str2 = strtok( buffer2, "\n");
if( str2!=NULL )
strcpy ((*current)->line[i], str2);
i++;
}
(*current)->left = NULL;
(*current)->right = NULL;
if ( i > 6 ){
printf("\nError FFFE : Data file is corrupt. Exiting...\n");
fputs( "Error FFFE : Data file is corrupt. Exiting...", stderr);
exit(0);
}
return **fp;
}
-
Btw, I can send you a copy of my entire program zipped and with the make file if you need.
-
first of all there are error in your code
Code:
FILE *addLoop( struct entry **current, FILE *fp, char name[])
as u are returning a file pointer back u dont need point to point refernce. cos u'r are returning back pointer position
Code:
while ( i<=4 && str!=NULL && !feof(**fp) ){
fgets( name, MAX, **fp );
strcpy( buffer, name);
strcpy( buffer2, buffer);
str = strtok( buffer, REMOVE);
str2 = strtok( buffer2, "\n");
if( str2!=NULL )
strcpy ((*current)->line[i], str2);
i++;
}
fgets function returns a EOF file at soon it reaches the end.
Code:
while(fgets(str, 100, fp) != EOF)
{
...
...
}
which solved the problem of fgets()
it would be better to open and close the file in the function rather than sending the file pointer to the fucntion and returning it
ssharish2005
-
> FILE ***fp
This many levels of indirection seems completely unnecessary.
I'd suspect you're not even calling it properly.
Without some supporting declarations, it's hard to say what is going on.
If you're building a linked list or a tree, then I strongly suggest you separate the "read the file" from the "add to data structure" code.
-
1. Why do you need FILE*** instead of FILE*?
2. str is not initialized before first use
3. you overwriting incoming string name, is it what you want to do?
4. feof should be checked after you tried to read from file before you actually using the data read
5. if ( i > 6 ) this cannot be achieved due to while ( i<=4 - loop exits when i==5
-
How would I do something like that :S ? Like have a function write to 2D arrary from the file, then send the 2D array to a function that adds the lines to the tree?
-
so write two function which does the follwing job
1. get the data from the file and place that in 2D array
2. send the 2D array to one ore function which addes that data from the "D to tree
hint: Function prototype
Code:
FILE * Getdata(char *filename); <--- to get datat from file
void AddToTree(struct node **root, char **data);
ssharish2005
-
Maybe start by posting some examples of the lines you read from the file, and the data structures you're working with.
Code:
while ( fgets( buff, sizeof buff, fp ) != NULL ) {
// validate and extract data
// if valid, add to data structure.
}
You can test the add to data structure with known good data without ever going anywhere near a file. When you know it works, then you add the file reading code, knowing that half the battle is already won.
Trying to do the whole thing at once at least quadruples the effort IMO.
-
Hmmmm, well I might as well give it a shot! Thanks!
-
How about this? Or should I do it all in main? (Im trying to make functions that I can use later, but I guess I am not doing that to well ^ ^; )
Code:
#include "lab05.h"
int buildTree ( struct head *soil, FILE *fp, char companyList [][WORD],
int *amount ){
char buffer [ MAX ];
char check [ MAX ];
char *tempS1;
int i;
struct entry *current;
// Create a new root if root is NULL
if ( soil -> root == NULL ){
soil -> root = (struct entry *) malloc (sizeof(struct entry));
soil -> root -> left = NULL;
soil -> root -> right = NULL;
// Null name string
strcpy (soil -> root -> name, "");
// Null line strings
for (i=0; i<5; i++)
strcpy(soil -> root -> line[i], "");
}
current = soil -> root;
// Run while loop till script/data file reaches EOF
while ( fgets( buffer, MAX, fp) != EOF ){
// Place tokenized string in tempS1 to check for blank lines
strcpy ( check, buffer );
tempS1 = strtok ( check, REMOVE );
// If line isn't blank, add entry to tree
if ( tempS1 != NULL ){
// Put company name into company list
strcpy (companyList[*amount], buffer);
fp = getData ( dataList, fp);
addData (dataList, soil )
*amount ++;
}
}
return 0;
}
-
I am really starting to freak out...
What am I doing wrong. I'll be back, need to take a walk. This is the thrid time I have rebuilt my adding to tree functions
Code:
///////////////////////////////////////////////////////////////////////
// Program : Lab05
// Function : getData
// File : getData.c
// Description : Extract upto x lines of data from file
// : quit when a blank line is found
// Variable Ref : dataList - list of company info
// : fp - File pointer
// : linesR - Number of lines returned
// : buffer - temporary line storage
// : buffer2 - temporary line storage
// : str - tokenized line storage
// : str2 - tokenized line storage
//////////////////////////////////////////////////////////
#include "lab05.h"
FILE *getData ( char *dataList[5], FILE *fp, int *linesR){
int i;
char buffer [MAX];
char buffer2 [MAX];
char *str;
char *str2;
i = 0;
while ( (fgets ( buffer, MAX-1, fp ) != EOF) ){
// Exit Prgm if 'i' is five, as there can only be
// 5 or less lines in the company data (0, 1, 2, 3, & 4)
if ( i == 5 ){
printf("\nError FFFE : Data file setup incorrectly. Exiting");
fputs("Error FFFE : Data file setup incorrectly. Exiting", stderr);
exit(0);
}
strcpy ( buffer2, buffer );
// Used to see if line is blank
str = strtok ( buffer, REMOVE );
// Take out the new line character
str2 = strtok ( buffer2, "\n" );
//
if ( str == NULL ){
return fp;
*linesR = i;
}
// Add str2 to 'dataList'
strcpy ( dataList[i] , str2);
printf("\ngetData 1.0 : dataList[%d] : <%s>", i, dataList[i]);
// Add one to i
i++;
}
*linesR = i;
return fp;
}
Code:
(c1400a01@pstcc11) #:~/1400/Lab05> make
gcc -Wall -c main.c
gcc -Wall -c promptFile.c
gcc -Wall -c fileOpen.c
gcc -Wall -c buildTree.c
buildTree.c: In function `buildTree':
buildTree.c:52: warning: comparison between pointer and integer
buildTree.c:62: warning: passing arg 1 of `getData' from incompatible pointer type
buildTree.c:64: warning: value computed is not used
gcc -Wall -c skipEntry.c
gcc -Wall -c upperAll.c
gcc -Wall -c displayTree.c
gcc -Wall -c getData.c
getData.c:18: conflicting types for `getData'
lab05.h:40: previous declaration of `getData'
getData.c: In function `getData':
getData.c:28: warning: comparison between pointer and integer
-
Well if you can't even use fgets properly, what hope is there?
It should be
while ( fgets ( buffer, sizeof buffer, fp ) !=NULL )
1. It returns NULL, not EOF on error or end of file
2. There is no need to do -1 to allow for the \0
Then fix your warnings.
For a start, make the prototype in you header file match the declaration in your code.
-
I got that fixed, the walked help to say the least. Thanks btw :D
(Yeah the fgets I looked up and it said it returned NULL. Though ssharish2005 said to use != EOF so thats half the reason I used it. ^ ^; Sorry)
I'll bug you guys some more if I need too