Split array by space into words - c

I got this code right here, which works.
#include <stdio.h>
#include <string.h>
int main()
{
char str1[100] = "Hello how are you";
char newString[10][10];
int i,j,ctr;
printf("\n\n Split string by space into words :\n");
printf("---------------------------------------\n");
j=0; ctr=0;
for(i=0;i<=(strlen(str1));i++)
{
// if space or NULL found, assign NULL into newString[ctr]
if(str1[i]==' '||str1[i]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=str1[i];
j++;
}
}
printf("\n Strings or words after split by space are :\n");
for(i=0;i < ctr;i++)
printf(" %s\n",newString[i]);
return 0;
}
but instead of char str1[100] I want to use an array of sentenceschar str1[2][100]
Meaning
char str1[2][100] = {"Hello how are you","I'm good, thanks"}
And these two sentences (or more) I want to be separated in separate words
char str1[100] = {"Hello","how","are","you"};
Actually, this is from a project for school, in which from a file, i have to store each sentence ended by '.'
If there is another way to store each sentece directly as words instead of sentences, it would be great help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LSIZ 128
#define RSIZ 10
void yodificacio(char* arr[], int index[], int n)
{
char* temp[n];
// arr[i] should be present at index[i] index
for (int i=0; i<n; i++){
temp[index[i]] = arr[i];
}
// Copy temp[] to arr[]
for (int i=0; i<n; i++)
{
arr[i] = temp[i];
index[i] = i;
}
}
int main()
{
int i = 0;
char *arr[] = {"Hey","there","how","are","you","all","today","idk"}; **Here I want the input to be char str1[2][100] = {"Hello how are you", "Im good thanks}, instead of char arr[] ...**
int index[] = {0,2,1,4,5,3,6,7};
int n = sizeof(arr)/sizeof(arr[0]);
yodificacio(arr, index, n);
printf("Reordered array is: \n");
for (int i=0; i<n; i++)
printf ("%s ", arr[i]);
return 0;
return 0;
}

Add an outer loop to process each sentence in the array.
int main()
{
char str1[2][100] = {"Hello how are you","I'm good, thanks"} ;
char newString[10][10];
int i,j,ctr;
printf("\n\n Split string by space into words :\n");
printf("---------------------------------------\n");
j=0; ctr=0;
for (int k = 0; k < sizeof(str1) / sizeof(str1[0]); k++) {
for(i=0;i<=(strlen(str1));i++)
{
// if space or NULL found, assign NULL into newString[ctr]
if(str1[k][i]==' '|| str1[k][i]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=str1[k][i];
j++;
}
}
}
printf("\n Strings or words after split by space are :\n");
for(i=0;i < ctr;i++)
printf(" %s\n",newString[i]);
return 0;
}

Related

Need some help how to enter a number and count it using array

I have to code in an array that can count an element. For example, if the user enters a 2, 2, 2, 1,1 then the user wants to count the number 2 then the result will be ELEMENT is 2 and FREQUENCY is 3. but I have a problem with the parts of " ENTER THE NUMBER YOU WANT TO BE COUNTED". I use scanf but when I run it I cannot enter any number.
Here's my code:
void frequency()
{
system("cls");
int num;
int count=0;
printf("Enter a number you want to be count: \n ");
scanf("i%", &num);
printf(" ELEMENT | FREQUENCY \n ");
for (i = 0; i<=n; i++)
{
if (a[i]==a[num])
count++;
}
printf(" \n %i ", num);
printf(" \t\t");
printf("%i \n ", count);
getch();
}
Your program requires understanding on two parts:
Get input and split input by delimiter, which can be done by using strtok.
Algorithm for finding the duplicated elements in an array.
#include <stdio.h>
#include <string.h>
int main() {
frequency();
return 0;
}
void frequency() {
char str[100];
printf("Enter a number you want to be count: \n ");
gets(str);
int init_size = strlen(str);
char delim[] = " ";
char *ptr = strtok(str, delim);
char *pch;
int arr[20];
int count = 0;
int ncount, i, j;
int a[count], Freq[count];
while(ptr != NULL) {
/*printf("'%s'\n", ptr);*/
/*Converts the string argument str to an integer (type int)*/
arr[count] = atoi(ptr);
/*strtok accepts two strings - the first one is the string to split, the second one is a string containing all delimiters*/
ptr = strtok(NULL, delim);
/*Initialize frequency value to -1*/
Freq[count] = -1;
count += 1;
}
/*Count the frequency of each element*/
for (i = 0; i < count; i++) {
ncount = 1;
for(j = i + 1; j < count; j++) {
/*Part to perform checking for duplicate elements*/
if(arr[i] == arr[j]) {
ncount++;
/*Make sure not to count frequency of same element again*/
Freq[j] = 0;
}
}
/*If frequency of current element is not counted*/
if(Freq[i] != 0) {
Freq[i] = ncount;
}
}
printf(" ELEMENT | FREQUENCY \n");
printf("-------------------------\n");
for (i = 0; i < count; i++) {
if(Freq[i] != 0) {
printf("\t%d\t\t\t%d\n", arr[i], Freq[i]);
}
}
}
Also, from your code:
You did not define i and n, which is required by your for loop. Also, since your for loop is for (i = 0; i<=n; i++), you have to define the value of n, which is the length of elements inputted by the user, in order to loop through the number of elements you expected.
int i, n, num;
...
...
for (i = 0; i<=num; i++)
Your scanf("i%", &num); should be scanf("%i", &num); instead.
You did not initialize your array a. You should have this line of code before assigning values to your array a. The value 20 can be adjusted by yourself depending on how many inputs are expected. Also, it can be coded in a flexible way instead of hardcoded as 20.
...
int i, num;
int count=0;
int a[20];
...
...
Lastly, it is a good practice to include the function's library before using it. In your case, you should include #include <conio.h> to use the getch() function.

How to make a program that scrambles the order of the words in a sentence from a file

I have a file with say 4 sentences, I know that there are 4 because each sentence has '.' at the end.
What I did was read from the file given and paste each sentence in a 2 dimensional array like so:
char sentence[0][200] = "Hello how are you."
char sentence [1][200] = "I'm good thanks. etc.
Here is the code for this:
int main()
{
char sentence[RSIZ][LSIZ];
char fname[20] = "t.txt";
FILE *fptr = NULL;
int i = 0;
int tot = 0;
char c;
int nrsentences = 0;
printf("\n\n Read the file and store the lines into an array :\n");
printf("------------------------------------------------------\n");
fptr = fopen(fname, "r");
// Check if file exists
if (fptr == NULL)
{
printf("Cant open the file %s", fname);
return 0;
}
// Sentences counter from file
for (c = getc(fptr); c != EOF; c = getc(fptr))
if (c == '.') // Increases if found '.'
nrsentences = nrsentences + 1;
fptr = fopen(fname, "r");
for (i=0; i<nrsentences; i++)
fgets(sentence[i], 200, fptr);
Then I would separate the this array in to words with this code:
(still in main(){})
char newString[10][30];
int j,ctr;
j=0; ctr=0;
for (int k = 0; k < nrsentences; k++) {
for(i=0;i<=(strlen(frases[k]));i++)
{
// if space or NULL found, assign NULL into newString[ctr]
if(sentence[k][i]==' '|| sentence[k][i]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=sentence[k][i];
j++;
}
}
}
printf("\n Strings or words after split by space are :\n");
for(i=0;i < ctr;i++)
printf(" %s ",newString[i]);
Then here is the problem (I think), the part of the scrambling code.
This works like this:
I give the code: the sentences and the inedex.
by default it is like this
index-> 0 1 2 3
sentence-> Hello how are you
but with this code it converts to this:
index-> 3 2 0 1
sentence-> you are Hello how
int index[] = {2,3,5,1,0,4,7,6}; //here I have a function that generates the random list(which I dont know yet how to make it work here
int n = nrsentences;
randomize(newString, index, n, nrsentences);
printf("Reordered array is: \n");
for (int i=0; i<n; i++)
printf ("%s ", newString[i]);
return 0;
}
Here is the randomize() function
void randomize(char* arr[], int index[], int n, int nrsentences)
{
printf("%d", n);
char* temp[n];
// arr[i] should be present at index[i] index
//for (int k = 0; k < nrsentences; k++){
for (int i=0; i<n; i++)
temp[index[i]] = arr[i];
// Copy temp[] to arr[]
for (int i=0; i<n; i++)
{
arr[i] = temp[i];
index[i] = i;
}
//}
}
And here is the index randomizer, which I dont know yet (didnt try) how to add it to the main, or randomize function.
int *random_number(int words)
{
int array[25];
int x, p, count;
int i=0;
srand(time(NULL));
while(i< words){
int r=rand()% words +1;
for (x = 0; x < i; x++)
{
if(array[x]==r){
break;
}
}
if(x==i){
array[i++]=r;
}
}
for(p=0;p<words;p++){
printf("%d ", array[p]);
}
return array;
}
or
int array[25];
int words = 5;
int x, p, count;
int i=0;
srand(time(NULL));
while(i< words){
int r=rand()% words +1;
for (x = 0; x < i; x++)
{
if(array[x]==r){
break;
}
}
if(x==i){
array[i++]=r;
}
}
for(p=0;p<words;p++){
printf("%d ", array[p]);

rearranging a char array with strncpy in C

I am trying to change the sorting of a the arr list which could consist of zero, one, two as the inputted and stored values for arr. The stringreplace function is meant to shift every single element by one so the new sorting would be one, two, zero. I am trying to replace the elements with one another by using the strncpy function but I think it is a bit faulty, how could i fix this?
strncpy function
char stringreplace( char a[], int b){
for(int j = 0; j > b -1; j++){
strncpy(a[j], a[j+1], sizeof(a));}
for(int j = 0; j > b; j++){
printf("%s",a[j]);}
}
main function
int main()
{
char input[100];
char arr[100]= {0};
int number;
printf("Input the number of strings: ");
scanf("%d", &number);
for(int i= 0; i < number; i++){
printf("Input the number of strings: ");
scanf("%s", input);
arr[i] = input;
}
stringreplace(arr, number);
return 0;
}
You may consider allocating strings dynamically, assigning a pointer for each string into an array words, and then rotating each pointer in the array to the left.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void lrot_words(char *words[], int n);
int main(void)
{
char *p, word[100], *words[100];
int i, num_words;
printf("Enter the number of words: ");
scanf("%d", &num_words);
for(i = 0; i < num_words; i++){
printf("Enter a word: ");
scanf("%s", word);
if ((p = malloc(strlen(word) + 1)) == NULL) {
fprintf(stderr, "Error: malloc failed\n");
exit(EXIT_FAILURE);
}
words[i] = strcpy(p, word);
}
lrot_words(words, num_words);
for (i = 0; i < num_words; i++) {
printf("%s\n", words[i]);
}
return 0;
}
void lrot_words(char *words[], int n)
{
char *temp = words[0];
int i;
for (i = 0; i < n - 1; i++) {
words[i] = words[i+1];
}
words[i] = temp;
}

I want to print the words seperated by space from input string

l have problem in this code, it stops working when it enters in the inner while loop, it should have printed the single word. For example the string is "My name is jack" the output should have been
my name is jack, every word after new line
int main (void)
{
int i=0,j=0;
char paragraph[1000],word[100];
printf("Enter the paragraph:\n");
gets(paragraph);
while(paragraph[i]!='\0')
{
int res = isspace(paragraph[i]);
if (res != 0)
{
word[i]='\0';
printf("\n");
j=0;
while(word[j] !='\0')
{
printf("%s",word[j]);
j++;
}
j=0;
}
word[j] = paragraph[i];
i++;
j++;
}
return 0;
}
#include <stdio.h>
#include <string.h>
int main()
{
char str1[100];
char newString[10][10];
int i,j,ctr;
printf("\n\n Split string by space into words :\n");
printf("---------------------------------------\n");
printf(" Input a string : ");
fgets(str1, sizeof str1, stdin);
j=0; ctr=0;
for(i=0;i<=(strlen(str1));i++)
{
// if space or NULL found, assign NULL into newString[ctr]
if(str1[i]==' '||str1[i]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=str1[i];
j++;
}
}
printf("\n Strings or words after split by space are :\n");
for(i=0;i < ctr;i++)
printf(" %s\n",newString[i]);
return 0;
}

Segmentation Fault: 11 C sometimes

I'm trying to run a program in C on my mac that asks the user to input a set of names. The program then sorts and capitalizes all the names and prints them capitalized and sorted. It then allows the user to search for a name. However, most of the time (but not every time) I try to run the code it returns a segmentation fault: 11 error. My guess is that the problem has something to do with fgets or my array but I don't really know.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SIZE 50
#define LENGTH 50
#define TRUE 1
#define FALSE 0
void printList(char names[SIZE][LENGTH], int length);
void toUpperCase(char names[SIZE][LENGTH], int length);
void sort(char names[SIZE][LENGTH], int length);
void startSearch(char names[SIZE][LENGTH], int length);
int binSearch(char names[SIZE][LENGTH], int l, int r, char x[LENGTH]);
int main(void){
char names[SIZE][LENGTH]; //stores the list of names
printf("Enter student names (q to stop)...\n");
int i = 0;
do {
printf("Student name #%d: ", i);
fgets(names[i], LENGTH, stdin); //fill the list of names
int len = strlen(names[i])-1; //fgets includes \n character
if(names[i][len] == '\n') //if the last character is \n
names[i][len] = '\0'; //change it to \0
if(strcmp(names[i], "") == 0)
printf("Invalid input: Type a name\n");
else
i++;
}
while(strcmp(names[i-1],"q")!=0 && i<SIZE); //Stop collecting names after input "q"
//or if the names array is full
int length = i-1; //# of names in the names array
sort(names, length);
toUpperCase(names, length);
printList(names, length);
startSearch(names, length);
printf("Done!\n");
return 0;
}
//Converts all the names in the names array to upper case
void toUpperCase(char names[SIZE][LENGTH], int length){
for(int i = 0; i < length; i++){
for(int j = 0; names[i][j]!='\n'; j++){
if(islower(names[i][j]))
names[i][j] = toupper(names[i][j]);
}
}
}
//sorts the names in the names array (bubble sort)
void sort(char names[SIZE][LENGTH], int length){
int i, j;
char temp[LENGTH];
for (i = 0; i < length-1; i++)
for (j = 0; j < length-i-1; j++)
if (strcmp(names[j],names[j+1])>0){
strcpy(temp, names[j]);
strcpy(names[j], names[j+1]);
strcpy(names[j+1], temp);
}
}
//prints the names in the names array
void printList(char names[SIZE][LENGTH], int length){
printf("Student list: [\n");
for(int i = 0; i < length; i++)
if(i == length-1)
printf("\t%s\n", names[i]);
else
printf("\t%s,\n", names[i]);
printf("]\n");
}
//The first method for searching the list
void startSearch(char names[SIZE][LENGTH], int length){
char search[LENGTH];
while(strcmp(search, "q")!=0){
printf("Enter a name to search (q to exit): ");
fgets(search, LENGTH, stdin); //gets the name to search
int len = strlen(search)-1;
if(search[len] == '\n')
search[len] = '\0';
if(strcmp(search, "q") == 0) //if entered value is q
break; //break out of the loop
//Since the list is all upper case change the search value to upper case
for(int j = 0; search[j]!='\n'; j++){
if(islower(search[j]))
search[j] = toupper(search[j]);
}
printf("Searching for %s ...\n", search);
// if binSearch returns true then the item is in the list
if(binSearch(names, 0, length-1, search) == TRUE)
printf("%s is in the list!\n", search); /
else
printf("%s is NOT in the list!\n", search);
}
}
//binary search for the names array
int binSearch(char names[SIZE][LENGTH], int l, int r, char x[LENGTH]){
while (l <= r)
{
int m = l + (r-l)/2;
if(strcmp(names[m], x) == 0)
return TRUE;
if(strcmp(names[m], x) < 0)
l = m + 1;
else
r = m - 1;
}
return FALSE;
}
I assume you're using fixed arrays of SIZE and LENGTH for learning purposes. For actual string-related work, you'd do well to heed kpra's advice and using the more complex, but more powerful, pointers (allocating them and deallocating at need).
In your reading loop you kill all the "\n"'s replacing them with zeroes.
Yet in your toUppercase() code you look for a "\n" instead of a 0x0. This risks blowing the buffer:
//Converts all the names in the names array to upper case
void toUpperCase(char names[SIZE][LENGTH], int length){
for(int i = 0; i < length; i++){
for(int j = 0; names[i][j]!='\n'; j++){
// what happens here if \n is not found and j exceeds SIZE?
if(islower(names[i][j]))
names[i][j] = toupper(names[i][j]);
}
}
}
You could replace \n with 0x0, but I think a safer loop would be:
for(int j = 0; j < SIZE; j++) {
if (yourstring[j] == 0) {
break;
}
This way you're sure never to overshoot SIZE, and the cycle is ended anyway if the end of string is found. Notice that this '\n' comparison is used also in the search loop.

Resources