Click here to Skip to main content
15,039,244 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
the code is written to sort names using dynamic allocation.i need to set limit for numbers of charaters entered by the columns and need to set limit to 32.the code is working but i dont know how to set limit for columns. columns need to set using static memoty.

What I have tried:

#include <stdio.h>
#include <stdlib.h>

/* Functions prototype */
void sort(char ** name, int count);
int my_strcmp(char * s1, char * s2);
void my_strcpy(char * dest, char * src);

int main()
{
    /* Declare local variables */
    char ** name, option;
    int count, i;

    do
    {
	/* Read count from the user */
	printf("Enter the number of names you want to sort : ");
	scanf("%d", &count);

	/* allocating memory dynamically for rows */
	name = (char **) malloc(count * sizeof(char*));

	/* Check whether memory is allocated or not */
	if (name == NULL)
	{
	    printf("Error: Memory not allocated\n");
	    return -1;
	}

	/* loop to read names */
	printf("Enter the %d names of length max 32 characters in each\n", count);
	for (i = 0; i < count; i++)
	{
	    printf("[%d] -> ", i);

	    /*allocating memory dynamically for columns */
	    name[i] = (char *) malloc(32 * sizeof(char));

	    /* check whether memory is allocated or not */
	    if (name[i] == NULL)
	    {
		printf("Error: Memory not allocated\n");
		return -1;
	    }

	    scanf("%s", name[i]);
	}

	/* Function call to sort the names */
	sort(name, count);

	/* Loop to print the sorted names */
	printf("The sorted names are:\n");
	for (i = 0; i < count; i++)
	{
	    printf("%s\n", name[i]);
	}

	/* Free the allocated memory */
	free(name);

	/* Check for continue */
	printf("Do you want to continue (y/n): ");
	getchar();
	scanf("%c", &option);

    } while (option == 'y');

    return 0;
}

/* Function body to sort the names in an array */
void sort(char ** name, int count)
{
    int i, j;
    char * temp = (char *) malloc(32 * sizeof(char));

    /* Buuble sort technique to sort the names */
    for (i = 0; i < count - 1; i++)
    {
	for (j = 0; j < count - i - 1; j++)
	{
	    if (my_strcmp(name[j], name[j + 1]) > 0)
	    {
		my_strcpy(temp, name[j]);
		my_strcpy(name[j], name[j + 1]);
		my_strcpy(name[j + 1], temp);
	    }
	}
    }
}

/* Function body to compare two strings */
int my_strcmp(char *s1, char *s2)
{
    while (*s1 == *s2)
    {
	if (*s1 == '\0' || *s2 == '\0')
	    break;
	s1++;
	s2++;
    }

    return (*s1 == '\0' && *s2 == '\0') ? 0 : (*s1 - *s2);
}

/* Function body to copy a string */
void my_strcpy(char * dest, char * src)
{
    while (*dest++ = *src++);
}
Posted
Updated 30-May-21 11:27am

The simple thing to do is to add a width specifier to your format string e.g
C
scanf("%32s\n", name[i]
However, if you enter a name with spaces in it e.g. "James Earl Jones", then using the %s format, scanf will read this as 3 separate words, not as a single line. Better would be to use a negative scanset. In this case we are interested in any characters up to a newline. We can tell scanf to do that, with a field with, using "%32[^\n]". Now scanf will read all characters in the input string, ending when either it has read 32 chars or finds a '\n'. But we still have an issue. If the name is over 32 chars, then the remaining characters are left in the input buffer waiting to be read on the next scanf. We don't want that! Additionally, unlike using "%s" the terminating newline is not read, and the next scanf will return an empty string (actually, it does not modify the target variable at all), so we need to remove the newline before we can proceed. That actually helps us, since after the scanf, we just need to do a tight loop to read in any remaining characters up to and including the newline e.g.
scanf("%32[^\n]", name[i]);
char c;
do {
  getchar(c);
}while(c !=' \n');

We still have a problem, though. We are allocating space for a name of 32 chars, and then reading in 32 chars. Given a long enough input string (32 or more characters), we actually overflow the string buffer we've allocated, since scanf adds a nul ('\0') to the end of the string. We need to either read in only 31 chars, or allow for the fact that we want to read in 32 chars, and so allocate string buffers of length 31.
Also, don't forget that when you call free(name), it only free's the block of memory associated with name = (char **) malloc(count * sizeof(char*)). This means that memory allocate for each individual name is no longer accessible (i.e. there is a memory leak). In this case, its not a serious problem, as the memory will be reclaimed when the program exits. But to properly clean up you should call free() on each member of the name array before you free the array itself.
   
Comments
Rahul Dicholkar 29-May-21 1:58am
   
sir the above code throws an error:
error: too many arguments to function ‘getchar’
50 | getchar(c);
| ^~~~~~~
In file included from class.c:1:
/usr/include/stdio.h:492:12: note: declared here
492 | extern int getchar (void);
also scanf("%32[^\n]", name[i]); will ensure that in each row more than 32 characters are not added but how to make sure where the total number of characters in all the rows are not more than 32?
sir the above code throws an error:
error: too many arguments to function ‘getchar’
50 | getchar(c);
| ^~~~~~~
In file included from class.c:1:
/usr/include/stdio.h:492:12: note: declared here
492 | extern int getchar (void);
also scanf("%32[^\n]", name[i]); will ensure that in each row more than 32 characters are not added but how to make sure where the total number of characters in all the rows are not more than 32?
   

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