String manipulation in C? - c

Okay I am trying to ask and sort names in C. I completed the code and it compiled without an error but I have a problem. When I input mixed characters that is Uppercase and Lowercase I get Uppercase sorted first and not in order. What should I do to my code ? Please anyone help me.
Code:
#include <stdio.h>
#include <string.h>
int main()
{
char name[30][25],temp[25];
int i,j,n;
printf("Enter how many students : ");
scanf("%d",&n);
for(i=0;i<n;i++);
{
printf("Enter the name of the student : ");
scanf("%s",name[i]);
}
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(strcmp(name[i],name[j])>0)
{
strcpy(temp,name[i]);
strcpy(name[i],name[j]);
strcpy(name[j],temp);
}
}
}
printf("The sorted names are : \n");
for(i=0;i<n;i++)
{
printf("%s\n",name[i]);
}
getch();
return(0);
}

The loops for your bubble sort are wrong - change:
for(i=0;i<n;i++)
{
for(j=i+j;j<n;j++)
{
to:
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
Alternatively just use qsort from the standard C library rather than trying to re-invent the wheel.

You have two options. One, convert the string to lower (or upper) before comparison. Secondly strcol each string, this puts k next to K etc. Both methods are destructive so you may need to create a work string and free it after comparison.

First of all your program is wrong. For example instead of
scanf("%s",&name[i]);
there has to be
scanf("%s", name[i]);
Or in this statement
for(j=i+j;j<n;j++)
there is used uninitialized variable j.
As for your question then you should convert strings to upper case using standard C function toupper declared in header <ctype.h>
Also it is better to use selection sort without copying strings every time when name[j] is less than name[i].

Multiple errors:
do not end the for loop with a semicolon
for(i=0;i<n;i++);
take a second look at these variables
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
as you described you compare incorrectly for your usecase
if(strcmp(name[i],name[j])>0)
This is a possible solution:
#include <stdio.h>
#include <string.h>
char * Inputs[] =
{
"3\n",
"Carl\n",
"Frank\n",
"carl\n"
};
int in = 0;
int main()
{
char name[30][25],temp[25];
int i,j,n;
printf("Enter how many students : \n");
sscanf(Inputs[in++],"%i",&n);
printf("You entered : %i\n", n);
for(i=0;i<n;i++)
{
printf("Enter the name of the student : \n");
sscanf(Inputs[in++],"%s",&name[i]);
printf("You entered : %s\n", name[i]);
}
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(stricmp(name[i],name[j])>0)
{
strcpy(temp,name[i]);
strcpy(name[i],name[j]);
strcpy(name[j],temp);
}
}
}
printf("The sorted names are : \n");
for(i=0;i<n;i++)
{
printf("%s\n",name[i]);
}
getch();
return(0);
}

Related

How can I write strings into a 2D ASCII character array?

Good day everyone,
I'm currently learning C through youtube and I have minimal knowledge about arrays. Is it possible for me to use an array to designate a place inside a pattern. e.g In a 20x20box Could I ask the user to say where he would like to place his name tag or brandname? I'm also wondering if I can create a pattern for a shield and know where the user would want to place his coat of arms using strings and loops.
#include <stdio.h>
#include <string.h>
int main()
{
int i,j, choice;
int Num=20;
/*
char brand[20][20]={{"BrandName"}};
printf("where should the brandname be placed?")
scanf("%d", &choice);
if(choice==1)//prints it on the left for example?*/
for(i=0;i<Num;i++)
{
for(j=0;j<Num;j++)
{
if(i==0||i==Num-1)
{
printf("*");
}
else if(j==0||j==Num-1)
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
return 0;
}

C program that adds data into a file then sorts the data entered

This is what I've got so far....
#include<stdio.h>
#include<string.h>
FILE *fp;
int n,num;
int i,j;
int result,index;
char name[50][50];
char jar[1024];
char temp[1000];
main()
{
clrscr();
fp=fopen("EXO-KAI.docx","a+");
printf("\nHow Many Names You Want to Add: ");
scanf("%d",&num);
printf("\nEnter Name:\n");
for(i=0;i<num;i++)
{
scanf("%s",&name[i]);
fprintf(fp,"%s\n",name[i]);
}
for(i=0;i<num;i++)
{
index=i;
for(j=i+1;j<num;j++)
{
result=strcmp(name[index],name[j]);
if(result>0)
index=j;
}
strcpy(temp,name[index]);
strcpy(name[index],name[i]);
strcpy(name[i],temp);
}
fp=fopen("EXO-LAY.docx","a+");
printf("\nThe Sorted Names are:\n");
for(i=0;i<num;i++)
{
printf("\n%s",name[i]);
fprintf(fp,"%s\n", name[i]);
}
fclose(fp);
getch();
}
In the first run, the sorted names are written into the file. In the second run, the program should read the written names in the file and sort it together with the new names. But this doesn't work. Can you please help me?
The problem in your code is that you are using bubble sort to sort all strings, but you put the string swap outside the inner loop. So this doesn't change the string order correctly when the string name[j] is greater than the string name[index]. So in order to do the sort on the string, you can do:
for(i=0;i<num;i++) {
for(j=i+1;j<num;j++) {
index = i;
result=strcmp(name[index],name[j]);
if(result>0) {
strcpy(temp,name[index]);
strcpy(name[index],name[j]);
strcpy(name[j],temp);
index = j;
}
}
}
So if the string name[j] is greater than name[index], the do the swap. Otherwise do nothing.
The bubble sort method you use has a complexity of O(N^2). So a better approach is using quick sort which on average has O(NlogN) complexity. To do this, you can use C's library function qsort() to achieve this. First you can define your own string comparator:
int my_str_compare(const void * a, const void * b)
{
return strcmp((char*) a, (char*) b);
}
Then you can invoke qsort function directly to replace the for loop in your code:
qsort (&name[0], num, 50, my_str_compare);
This will does the same sorting as yours but in general faster.

Returning Array of pointers to string

I am confused and clueless as how can I return an Array of pointers to a String(Basically 2D array) from a function.
What I did(or about to do )in this code is , first insert words/names and then stored it in the array and also input the number 'n'. Than I passed this array and number into the function and their extracted the last 'n' names/words from the array and print that in the main.
Here is my code :
#include<stdio.h>
#include<conio.h>
#include<alloc.h>
#include<string.h>
char** fun(char *s[5],int no)
{
char *f[5];
int i,j=0;
for(i=5-no;i<5;i++)
{
f[j]=(char*)malloc(strlen(s[i])+1);
strcpy(f[j],s[i]);
j++;
}
/*for(j=0;j<no;j++) //I did it just to check whether 'f' stores the last 'n' names.
printf("\n%d. %s",j+1,f[j]);*/
return f;
}
void main()
{
char *name[5],*str,*list[5];
int i,n;
clrscr();
printf("Enther the Names of the list : " );
for(i=0;i<5;i++)
{
printf("%d. ",i+1);
str=(char*)malloc(30);
gets(str);
name[i]=(char*)malloc(strlen(str)+1);
strcpy(name[i],str);
free(str);
}
clrscr();
printf("\nEntered Names are : ");
for(i=0;i<5;i++)
printf("\n%d. %s",i+1,name[i]);
printf("\n Enter the no. :");
scanf("%d",&n);
*list=*fun(name,n); // I am little confused as to how should I wrote this ?
for(i=0;i<n;i++)
printf("\n%d. %s",i+1,list[i]);
getch();
}
Suppose I gave the Input as :
1.the
2.there
3.this
4.that
5.therefore
Enter the No.: 3
Output:
1.this
2.<Some special characters>
3.<Some special characters>
I would more interested in the method which uses the pointer approach .
PS: I am Using Turbo C/C++ IDE as I am in a Learning phase of C .
As H2CO3 pointed out, define the fun as fun(list, name, n); where list is your output list of string. Pass the list from main(), fill it up inside fun().
You can not define array of pointers of char locally(which will allocate it on stack. scope of it is inside that function only) and use it globally.
inside fun() you can use
char f = (char)malloc(sizeof(char*[5])); (allocate memory on heap which you can use it globally)
instead of
char *f[5];
code should be:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include <malloc.h>
char** fun(char *s[5],int no)
{
char **f = (char**)malloc(sizeof(char*[5]));
int i,j=0;
for(i=5-no;i<5;i++)
{
f[j]=(char*)malloc(strlen(s[i])+1);
strcpy(f[j],s[i]);
j++;
}
/*for(j=0;j<no;j++) //I did it just to check whether 'f' stores the last 'n' names.
printf("\n%d. %s",j+1,f[j]);*/
return f;
}
void main()
{
char *name[5],*str,**list;
int i,n;
printf("Enther the Names of the list : " );
for(i=0;i<5;i++)
{
printf("%d. ",i+1);
str=(char*)malloc(30);
gets(str);
name[i]=(char*)malloc(strlen(str)+1);
strcpy(name[i],str);
free(str);
}
printf("\nEntered Names are : ");
for(i=0;i<5;i++)
printf("\n%d. %s",i+1,name[i]);
printf("\n Enter the no. :");
scanf("%d",&n);
list=fun(name,n); // I am little confused as to how should I wrote this ?
for(i=0;i<n;i++)
printf("\n%d. %s",i+1,list[i]);
getch();
}

Sorting letters C programming

I'm trying to make the letters of a matrix sort alphabetically and then be written out in a single string.For instance you type ten words,which are then stored in an array,and every letter has its place in the matrix then,right?But after I've written the words I want to bunch all the letters of all words together and then type all the letters out in alphabetical order.This is what I have so far:
#include <stdio.h>
#include <conio.h>
int main(void){
int i, j, k, f, n, m;
//was trying out various things,that's why I have so many useless ints up there
char word[10][15],temp;
for(i=0;i<=9;i++)
{
printf("Type in wword number %d: ", i+1);
gets(word[i]);
}
for(k=i-1;k>=0;k--)
{
for(m=0;m<k;m++)
if(word[k][f] > word[m][n])
{
temp=word[k][f];
word[k][f]=word[m][n];
word[m][n]=temp;
}
}
printf("Letters alphabetically sorted: ");
for(i=0;i<=9;i++){
for(j=0;j<=14;j++){
printf("%d",word[i][j]);
}
}
printf("\n");
getch();
}
I'm still in the process of learning about matrixes and I've gotten pretty familiar with arrays by now.But the sorting thing is confusing me,this was my attempt but it doesn't work.It lets you write all the words,and then it crashes.
What am I doing wrong here?And how do I correct it?
In your code here:
temp=word[k][f];
word[k][f]=word[m][n];
word[m][n]=temp;
the variables n and f are used uninitialised. That will most likely be the cause of the crash.
f,n are uninitialized. It has garbage and is the reason for crashing at this point.
for(k=i-1;k>=0;k--)
{
for(m=0;m<k;m++)
if(word[k][f] > word[m][n]) // f,n are uninitialized and are error prone
I think this will work..Please excute and tell me..
void main()
{
char word[10][15],temp,sorted_word[15];
int i,j,ii,k,l=0;
for(i=0;i<=9;i++)
{
printf("Type in wword number %d: ", i+1);
gets(word[i]);
}
for(i=0;i<=9;i++)
{
for(j=0;word[i][j]!='\0';j++)
{
ii=i;
for(k=j+1;1;k++)
{
if(ii==9 && word[ii][k]=='\0')
break;
if(word[ii][k]=='\0')
{
ii++;
k=0;
}
if(word[i][j]>word[ii][k])
{
temp=word[i][j];
word[i][j]=word[ii][k];
word[ii][k]=temp;
}
}
sorted_word[l++]=word[i][j];
}
}
sorted_word[l]='\0';
printf("%s",sorted_word);
getch();
}
here the
for(i=0;i<=9;i++)
{ printf("type in wword %d: ",i+1);
gets(word[i]);
}
gets (word[1]);
stores the value from word[1] onwards but where as the character array starts from
word[0].
may be this is not the full solution for u problem
this issue may help u in solving your doubt.

Strings taken from user in C are being scrambled

I have written the following C code to get in a list of strings from the user. But the stored strings are giving out weird values.
#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING_LENGTH 50
void readInStrings(char* arr[],int n)
{
int i=0;
char line[MAX_STRING_LENGTH];
for(i=0;i<n;i++){
arr[i]=malloc(MAX_STRING_LENGTH);
printf("Enter another string : ");
scanf("%s",&arr[i]);
//fgets(&arr[i],MAX_STRING_LENGTH,stdin);
}
printf("Strings read in correctly.... \n");
printf("Displaying out all the strings: \n");
for(i=0;i<n;i++){
printf("%s\n",&arr[i]);
}
}
void testStringInputs()
{
printf("Enter the number of entries : ");
int n;
scanf("%d",&n);
char* strings[n];
readInStrings(strings,n);
}
Input Sample:
Enter the number of entries : 3
Enter another string : Alladin
Enter another string : Barack Obama
Enter another string : Strings read in correctly....
Displaying out all the strings:
AllaBaraObama
BaraObama
Obama
Problems:
1) Why is one string not taken in as input at all?
2) Why are the displayed strings scrambled like that?
The problem is the same if I use gets() or fgets() in place of scanf().
arr[i] is already a pointer, you don't need the &
Removing the & (as the first answerer noted) in scanf("%s",&arr[i]); and in printf("%s\n",&arr[i]); did the trick for me. Also, note if you compiled with warnings at their highest, your compiler would have told you right away that the & was misplaced.
Its better to use an array of arrays(two dimensional) instead of array of pointers.
I had a tough time correcting your code. So I changed the code to this
#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING_LENGTH 50
void readInStrings(char (*arr)[MAX_STRING_LENGTH],int n)
{
int i;
for(i = 0 ; i< n+1; ++i)
fgets(*(arr+i),MAX_STRING_LENGTH,stdin);
printf("Strings read in correctly.... \n");
printf("Displaying out all the strings: \n");
for(i=0;i< n+1;i++){
printf("%s",arr[i]);
}
}
int main()
{
printf("Enter the number of entries : ");
int n;
scanf("%d",&n);
char strings[n][MAX_STRING_LENGTH];
readInStrings(strings,n);
return 0;
}

Resources