Thread: Using a linked list globally and File I/O

  1. #31
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I assume the number in the list to delete. X numbers from head. That's what I gather from the code.
    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.

  2. #32
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Oh ok, I get it. I'm used to seeing previous used in doubly linked lists and numbers being zero based, so that messed me up a little.

    But when you enter in 0 for acount, it still deletes one. Is that what you want?

  3. #33
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    Deleting the first person on the list works fine, because we never enter the loop anyway, so it doesn't matter.

    Here's the full code along with the process that calls it so that you can fully understand how it works.

    Code:
    void search(struct node** head, int afunc)
    /* afunc: 0 = delete, 1 = print */
    {
    	int choice;
    	long int aa;
    	char lastname[20];
    	int count = 0;
    	struct node* current = *head;
    	
    	printf("\nAnazhthsh vash se:\n\n");
    	printf("1. ASM\n");
    	printf("2. Epitheto\n\n");
    	printf("Epilogh: ");
    	fflush(stdin);
    	scanf("%1d", &choice);
    	
    	switch(choice)
    	{
    		case 1:
    		printf("\nDwse ASM: ");
    		scanf("%6ld", &aa);
    		while (current != NULL && current->soldier.aa != 0) {
    			count++;
    			if (aa == current->soldier.aa) {
    				if (afunc == 1) {
    					printone(&current, 0);
    					printf("\n");
    					fflush(stdin);
    					getchar();
    					return;
    				}
    				else goto delrecbreak;
    			}
    			current = current->next;
    		}
    		printf("Den vrethike o ASM pou dwsate.\n");
    		case 2:
    		printf("\nDwse epitheto: ");
    		fflush(stdin);
    		fgets(lastname, 20, stdin);
    		lastname[strlen(lastname)-1] = '\0';
    		while (current != NULL && current->soldier.aa != 0) {
    			count++;
    			if (strcmp(lastname, current->soldier.lastname) == 0) {
    				if (afunc == 1) {
    					printone(&current, 0);
    					printf("\n");
    					fflush(stdin);
    					getchar();
    					return;
    				}
    				else goto delrecbreak;
    			}
    			current = current->next;
    		}
    		printf("Den vrethike stratiwths me to epitheto pou dwsate.\n");
    	}
    	delrecbreak:
    	if (afunc == 0) delrec(&*head, count);
    }
    
    void delrec(struct node** head, int acount)
    {
    	int i;
    	struct node* current = *head;
    	struct node* previous = NULL;
    	
    	for (i=1;i<=acount-1;i++)
    	{
    		previous = current;
    		current = current->next;
    	}
    	
    	if (previous == NULL) *head = current->next;
    	else previous->next = current->next;
    	free(current);
    }
    And because I bet you don't really understand greeklish, what search() does is ask the user if he wants to search for a certain soldier via index or their surname, and depending on afunc (whether the user selected "search and delete" or "search and print" in the main menu), search prints the current soldier or passes their linked list "index" to delrec(), which goes to delete that record.
    Last edited by Leftos; 01-04-2008 at 03:25 PM.

  4. #34
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    yeah I'm not getting this. Could you post the whole program?

    and is this for a homework assignment? do you have to use those function prototypes?
    Last edited by robwhit; 01-04-2008 at 04:15 PM.

  5. #35
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    Yeah, this is a college assignment, our final assignment for "Procedural Programming: C". As I mentioned in the first post, we have to make a program that opens a database of soldiers and has their index, first name, last name, date that they entered the army, date they're getting out, number of days they're allowed out of the army, and number of days they've offered their services. I'm not good with army terminology in English, so that part may not be all that clear.

    I'm using those function prototypes only because I want to. We could do it all in main() if we wanted, but we've learned how to use separate functions so they're expecting us to use them, a bit up to a lot.

    I could post the whole assignment (it's unfinished anyway, only load, save, create entry, search and print, search and delete, print all work, the other two army specific functions I haven't even started yet) if you still want to, or I could explain the above procedure more.

    As for fflush(stdin), I had it in my mind as a recommendation from another user around here, who obviously hadn't read the FAQ. So should I increase all array sizes by 1 to avoid them filling up? Or is there some other way that works both in Windows and UNIX in order to clear the standard input buffer?

  6. #36
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    For arrays - just don't go over bounds. No matter how many idexes you create in there, there's always a chance you'll do out of bounds, so do proper checking first.
    And for second, you can use fgets and you don't have to worry about the input buffer at all, which is the preferred solution.
    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.

  7. #37
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    Well, I have flushes all over the create entry function, because either the scanf's or fgets' kept the \n character in their buffers and the next "get string" command got overriden with \n as input. What could I do to avoid such a thing happening?

  8. #38
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    fgets reads everything into the buffer and does not leave dangling newlines in the input buffer.
    You don't like the newline? You can get rid of it by erasing the last element in a string array.
    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.

  9. #39
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    I'm already doing that, by insterting \0 in strlen-1. Let me check which function keeps the \n and I'll get back and edit.

    EDIT: Found it. fgets following scanf is overriden.

    Code:
    	printf("\n");
    	printf("Dwse ASM stratiwth (6 pshfia): ");
    	scanf("&#37;6ld", &soldiers.aa);
    	
    	printf("Dwse onoma stratiwth: ");
    	fgets(soldiers.firstname, 20, stdin);
    	soldiers.firstname[strlen(soldiers.firstname)-1] = '\0';
    The fgets doesn't give me a chance to input at all.
    Last edited by Leftos; 01-05-2008 at 04:45 AM.

  10. #40
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Using a linked list globally and File I/O
    Hmm.. I finally read the title and it makes sense now. So many mistakes by me in one thread....

    /me goes and sits in the corner now...

  11. #41
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    What kind of mistakes? I found your explanations pretty well-based.

    Still, can anyone recommend me what course of action should I take in the above part of code so that the fgets command doesn't get overriden by what's remaining in the stdin buffer?

  12. #42
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    use fgets for ALL input
    and than parse it with something like sscanf
    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

  13. #43
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    Example, please?

  14. #44
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    http://faq.cprogramming.com/cgi-bin/...&id=1043284385

    see OPTION 3 Read As A String and Convert
    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

  15. #45
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    I'm getting annoyed with the newline problem. If anyone could provide a solution, please do so. Here's the code.

    Code:
    int main(int argc, char *argv[])
    {
    	int choice;
    	char choice2[3];
    	
    	/* if (argc!=2) {
    	printf("Usage: SOLDIERSDB <database>\n");
    	exit(1);
    	}
    	
    	struct node* head = loadfile(*argv[1]); */
    	struct node* head = loadfile("soldiers");
    
    	for(;;)
    	{
    		choice = menu();
    		switch(choice)
    		{
    			case 1:	create(&head); continue;
    			case 2:	search(&head, 0); continue;
    			case 3:	search(&head, 1); continue;
    			case 4:	printall(&head); continue;
    			case 5:	printf("5 not completed.");	continue;
    			case 6:	printf("6 not completed.");	continue;
    			case 7:	savedb(head, "soldiers"); continue;
    			/* Exit */
    			case 8:
    			printf("\nAll unsaved changes will be lost. Are you sure you want");
    			printf("\nto exit?\n");
    			fgets(choice2, 3, stdin);
    			choice2[strlen(choice2)-1] = '\0';
    			if (choice2=="y") break;
    			else continue;
    			/* Not a valid menu selection */
    			default:
    			continue;
    		}
    		break;
    	}
    	return 0;
    }
    
    int menu()
    {
    	int choice;
    	
    	printf("\nDialekste epilogh:\n\n");
    	printf("1. Eisagwgh stratiwth\n");
    	printf("2. Diagrafh stratiwth\n");
    	printf("3. Ektypwsh stratiwth\n");
    	printf("4. Ektypwsh olwn\n");
    	printf("5. Epilogh twn N prwtwn stratiwtwn pou exoun dikaiwma na\n");
    	printf("   paroun M meres adeia.\n");
    	printf("6. Epilogh twn N prwtwn stratiwtwn gia yphresia\n");
    	printf("7. Apo8hkeysh vashs dedomenwn.\n");
    	printf("8. Exodos.\n");
    	printf("\nEpilogh: ");
    	
    	fgets(tempbuf, 3, stdin);
    	choice = atoi(tempbuf);	
    	return choice;
    }
    Never mind the greeklish. I choose option 8 at the menu, but then even if I type y at the prompt to exit, the program just displays the menu again.

    EDIT: This works:

    Code:
    fgets(choice2, 3, stdin);
    choice2[strlen(choice2)-1] = '\0';
    if (choice2[0]=='y' && choice2[1]=='\0') break;
    Last edited by Leftos; 01-07-2008 at 10:41 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. linked list versus array
    By FoodDude in forum C++ Programming
    Replies: 18
    Last Post: 08-22-2005, 10:57 AM