Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
When user choose 1. Add Data, program have to receive only INTEGER data.
If user input UN-INTEGER data(like 5.69, 8.3), it should print "Error : Input value is invalid".

And, when user choose 3. Display Data, program have to print only 5 data in each line.
(like

Display Data :
1 6 16 8 30
9 65 25 7 9
15 36 95 4 2
    .
    .
    .

)

I can't make it. I hold it almost 5 hours, but I can not find how I make it.
plzz help.. it make me mad...:Q
C++
#include <stdio.h>
#include <stdlib.h>
#define FUNC_SIZE 4  // size of pointer function array

// structure declare

typedef struct node_record {
 int nData;
 struct node_record *next;
} _node;

typedef _node* list_node;  // structure pointer's data type declare
list_node head = NULL;  // structure pointer variable declare
int list_menu(int*);    // menu function
int input_num(int*, int);   // input function
int insert_node(void);   // input in node function
int delete_node(void);   // delete node's content function
int print_node(void);   // print function
int end_proc(void);    // quit function

// main function
int main(void)
{
	int nSelect=0, nRetry=1;  // select menu,  repeat variable
	int (*func_node[FUNC_SIZE])(void)={insert_node, delete_node, print_node, end_proc};  // pointer function array declare and initialize to functions
	while(nRetry)  // repeat
	{
		list_menu(&nSelect);  // call main function
		nRetry = func_node[nSelect-1]();   //call correspond function
	}
	return 0;
}

// menu function
int list_menu(int* pSelect)
{
	puts("********MENU********");
	puts("* 1. Insert        *");
	puts("* 2. Remove        *");
	puts("* 3. Print         *");
	puts("* 4. End           *");
	puts("********************");
	do 
	{
		fflush(stdin);
		printf("*Choice : ");
		scanf_s("%d", pSelect);   // input
	} while(*pSelect > 4 || *pSelect < 1);   // choose range
	return 0;
}

//  input function
int input_node(int* pNum, int nFlag)
{
	printf("*%s : ", (nFlag == 1)?"Input Value":"Want to delete Value");
	scanf_s("%d", pNum);  // input
	return 0;
}

// input function of list
int insert_node(void)
{
	list_node temp, ptr, preptr;  // structure pointer variable declare
	int nData=0;   // variable for input
	preptr = head;  // structure pointer variable "head" is stored in "preptr"
	temp = (list_node)malloc(sizeof(_node));   // allocate memory in variable "temp"
	input_node(&nData, 1); 
	if(temp == NULL)  // if memory doesn't be allocate very well
	{
		printf("*Memory wasn't enough.");
		exit(1);   // quit  unusually
	}
	temp->nData = nData;  // store input data in "temp"'s parameter "nData"
	if(head == NULL || head->nData > nData)  // the case "head" is "NULL" OR the case "head"'s parameter nData is larger than input value
	{
		temp->next = head;  // "head"'s address(at this time) is stored in "next" parameter of "temp" structure pointer
		head = temp;    // "temp" is stored in "head" so "head" is changed
	}
	else  // exception
	{
		ptr = preptr->next;  // address value that "next" of "preptr(head)" has is copied in "ptr"
		while(ptr != NULL)  // the case that "ptr" isn't NULL
		{
			if.(ptr->nData > nData)  //compare with "nData"value of "ptr" and Input value - the case that ptr->nData is larger than Input value
				break;   // quit repeat sentence
			preptr = ptr;   // copy "ptr"(in this time) to "preptr" (increase  one by one)
			ptr = ptr->next;  // "ptr->next"(in this time) copy address value to "ptr"(increase  one by one)
		}
		temp->next = ptr;   // store address of "ptr"(in this time) in "temp->next"(temp --> ptr)
		preptr->next = temp;  // store address of "temp" in "preptr->next"(preptr --> temp)
	}
	return 1;
}


// delete function of list
int delete_node(void)
{
	list_node preptr, ptr;  // structure pointer variable declare
	int nData=0;     // data to delete
	input_node(&nData, 2); // input to delete value
	if(head == NULL)   // if "head" is "NULL", there are no data
	{
		puts("*Data does not exist.");
	}
	else if(head->nData == nData)  // if "head->nData" is same with data that want to delete 
	{
		preptr = head;    // store address of "head" in "preptr"
		head = preptr->next;  // address value of "preptr(head)->next" is replaced to "head"("head" is change to address value that "head" points)
		free(preptr);     // clear "preptr" memory
		puts("*Data was erased.");  // print message
		return 1;
	}
	else
	{
		preptr = head;    // store address of "head" in "preptr"
		ptr = preptr->next;   // store next address that "preptr(head)" (that stored above is point) in "ptr"
		while(ptr != NULL && ptr->nData != nData)  
			preptr = ptr;    
			ptr = ptr->next;   
		}
		
		if(ptr == NULL)  
			puts("*Corresponding data does not exist."); 
		else 
		{
			preptr->next = ptr->next;  // give address of "ptr->next" to "preptr->next" so "pretr" points next address that "ptr" is pointing
			free(ptr);       // clear memory about "ptr"
			puts("*Data was erased.");  // print message
		}
	}
	return 1;
}

// list print function
int print_node(void)
{
	int nIdx=1;   // print counter
	list_node preptr;  // structure pointer variable
	preptr = head;  // copy "head" to "preptr"
 
	if(preptr == NULL)  // there is no data when "preptr(head)" is "NULL"
		puts("*Data does not exist.");
	else  // case that isn't "NULL"
	{
		printf("*Display Data : ");
		while(preptr != NULL)  // repeat when "preptr" isn't "NULL"
		{
			printf("%d ",  preptr->nData); //print data
			preptr = preptr->next;  // substitute "preptr->next"'s address value(in this time) to "preptr"
		}
		printf("\n");
	}
	return 1;
}

// quit function
int end_proc(void)
{
	list_node temp;  // structure pointer variable
 
	while(head != NULL)   // case that "preptr(head)" isn't "NULL"
	{
		temp = head;    // copy "head" to "preptr"
		head = temp->next;  // copy "temp(head)->next"'s address to "head"
		free(temp);     // clear "temp" variable memory of this time
	}
	puts("Quit the program.");    // print quit message
	return 0;
}
Posted
Updated 27-May-12 4:10am
v3
Comments
Sergey Alexandrovich Kryukov 28-May-12 2:08am    
"It makes me mad" and information on how much time have you used to solve the problem is useless information (unless someone wanted to estimate your capabilities, but this issue is irrelevant to the question :-)
--SA

When you asked this question earlier this morning (please help about linked list in c[^]) I told you what you need to do.

Ok, I'll try a little more detail.
The scanf_s function returns a value, which tells you how it all worked.
If it converted numbers, then it returns the count of the numbers converted. So, if the user enters a single number which matches your format, it will return 1.
If the user enters data which does not match your format, it will return EOF.

Your input_node function also returns a value - currently, it is always 0.

What I would do is make input_node return true (i.e. nonzero) if the conversion succeeded, and false (i.e. zero) if it failed:
All this needs is to change your routine to:
C#
int input_node(int* pNum, int nFlag)
{
    printf("*%s : ", (nFlag == 1)?"Input Value":"Want to delete Value");
    return (scanf_s("%d", pNum) != EOF);
}

You can then check this return value when you call your function, and if it is false there is no number so you need to print your message.
C++
if (!input_node(&nData, 1))
       {
       // Bad input - report it.
       printf("Error : Input value is invalid");
       }
    else
       {
       ...



BTW: Well done on adding the comments - but try to make them describe what the code is trying to achieve, not what the C language instruction is doing.
For example:
C++
ptr = ptr->next;  // "ptr->next"(in this time) copy address value to "ptr"(increase  one by one)
Is better as
C++
ptr = ptr->next;  // Move to next node
 
Share this answer
 
Comments
Mohamed Mitwalli 27-May-12 9:34am    
5+
In the solution of OriginalGriff you have learned how to check whether scanf_s returned the correct number of inputs. But in order to test whether the input is a number and just a number you need to do a little more. Consider the case, when the user inputs:

12abc


scanf_s will read the number 12 and give you as return value 1 (as it has read input variable). But it did not recognize the additional "abc", but just stopped reading at the 'a'. To make sure that there is no additional input besides the number, you could for instance look at the next character in the input stream:

int rc = scanf_s ("%d", &num);
int nextChar = fgetc (stdin);
if (rc != 1 || nextChar != '\n')
     return false;


In the correct case we expect to find the newline character which has not been consumed by scanf_s. Everything else represents an error condition.

Now to your second question: How can we manage to print at max five numbers per line?

There are many techniques to achieve that. The simplest is introducing an additional counter in your print loop and when it counts to 5, add a newline to the output, like this:

int colCounter = 0;
...
printf ("*Display Data : ");
while (preptr != NULL)
{
    // advance to next line when we have printed five columns
    if (colCounter >= 5)
    {
        printf ("\n");
        colCounter = 0;
    }

    // print a single element
printf("%d ",  preptr->nData);
    ++colCounter;

    // advance to next packet in the sorted list
preptr = preptr->next;
}
printf("\n");


Easy, isn't it.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900