convert an string with multiple words to an array of char - c

Imagine I have the following string:
char input[] = "this is an example";
I want to take this string and make each word an entry in an array,
how could I get this into an array like this:
char inputArray[] = {"this","is","an","example"};

Either you do not know exactly what you want or you want the following:)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char input[] = "this is an example";
size_t n = 0;
for ( char *p = input; *p; )
{
while ( isspace( ( unsigned char )*p ) ) ++p;
if ( *p )
{
++n;
while ( *p && !isspace( ( unsigned char )*p ) ) ++p;
}
}
char * inputArray[n];
size_t i = 0;
for ( char *p = strtok( input, " \t" ); p != NULL; p = strtok( NULL, " \t" ) ) inputArray[i++] = p;
for ( i = 0; i < n; i++ ) puts( inputArray[i] );
return 0;
}
The program output is
this
is
an
example

Related

qsort turns all values of array to null

I have a program which reads in the lines of a text file and stores them in linesArr, I have also defined a function compFunc which takes two strings as inputs, makes copies of them and converts the copies to lowercase before returning the value of strcmp(copy1, copy2). I am trying to use this function to sort linesArr into alphabetical order with qsort(linesArr, size, 255, compFunc. But the values in the array turn from {"Bob", "James", "Alice"} to {(null), (null), (null)}.
This is how linesArr is initialised.
char **linesArr = (char**)malloc(size*sizeof(char));
for (int i = 0; i < size; i++) {
linesArr[i] = (char*)malloc(255*sizeof(char));
}
And it it filled with values from the text using the file pointer fp
for (int i = 0; i < size; i++) {
fgets(line, 255, fp);
strcpy(linesArr[i], line);
}
Why is qsort deleting the values in the array?
For starters this memory allocation
char **linesArr = (char**)malloc(size*sizeof(char));
^^^^^
is incorrect, You need to write
char **linesArr = (char**)malloc(size*sizeof(char *));
^^^^^^
Secondly the call of qsort must look like
qsort(linesArr, size, sizeof( char * ), compFunc);
because the array pointed to by the pointer linesArr is an array of pointers.
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int compFunc( const void *a, const void *b )
{
const char *s1 = *( const char ** )a;
const char *s2 = *( const char ** )b;
while ( *s1 && tolower( ( unsigned char )*s1 ) == tolower( ( unsigned char )*s2 ) )
{
++s1;
++s2;
}
return tolower( ( unsigned char )*s1 ) - tolower( ( unsigned char )*s2 );
}
int main(void)
{
enum { size = 3, len = 255 };
char **linesArr = malloc( size * sizeof( char * ) );
for ( size_t i = 0; i < size; i++ )
{
linesArr[i] = malloc( len * sizeof( char ) );
}
char line[len];
for ( size_t i = 0; i < size; i++ )
{
fgets( line, sizeof( line ), stdin );
line[ strcspn( line, "\n" ) ] = '\0';
strcpy( linesArr[i], line );
}
qsort( linesArr, size, sizeof( *linesArr ), compFunc );
for ( size_t i = 0; i < size; i++ )
{
puts( linesArr[i] );
}
for ( size_t i = 0; i < size; i++ )
{
free( linesArr[i] );
}
free( linesArr );
return 0;
}
The program output might look like
Bob
James
Alice
Alice
Bob
James

How to Reverse a sentence word by word?

I was trying to reverse a sentence word by word. (how are you -> you are how) First of all I create a char sentence and reverse and temp. Sentence given by user to reverse. Temp catches the word to change the location in the sentence.Then I use strcat to concatenate each word. Here is the problem. I can find the word which is end of the sent(takes input) but when I'm trying to concatenate to reverse, it add this word to sentence and an error occurs. What's the problem?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* subs(char* temp, char* src, int start, int end);
int main() {
char sent[15]; //input sentence
char rev[15]; // output sentence
char *temp=(char*)calloc(1,sizeof(char)); //for the word
scanf(" %[^\n]%*c", &sent); // takin' input
int i, end, start;
i = strlen(sent);
//find the beggining and ending of the indexes of the word in sentence
while (i > 0) {
while (sent[i] == ' ') {
i--;
}
end = i-1;
while (sent[i] != ' ') {
i--;
}
start = i + 1;
//add the word to temp and concatenate to reverse
temp=subs(temp, sent, start, end);
strncat(rev, temp,end-start+3);
}
rev[strlen(sent)] = '\0';
printf("%s", rev);
return 0;
}
char* subs(char* temp, char* src, int start, int end) {
int i = 0, control;
// resize the temp for the wırd
temp = (char*)realloc(temp,end-start+3);
for (; i < (end - start) + 1; i++) {
control = (start + i);
temp[i] = src[control];
}
//adding blank and null character to end of the word.
temp[i] = ' ';
temp[++i] = '\0';
return temp;
}
I will just copy my good answer from this question that was not yet closed Reverse a string without strtok in C
. So I can not use this reference to close your question as a duplicate.
A standard approach is to reverse each word within a string and then to reverse the whole string.
The standard C function strtok is not appropriate in this case. Instead use the standard C functions strspn and strcspn.
Here you are.
#include <stdio.h>
#include <string.h>
static char * reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[ i ];
s[ i ] = s[ n - i - 1 ];
s[ n - i - 1 ] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t";
char *p = s;
while ( *p )
{
p += strspn( p, delim );
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
reverse( q, p - q );
}
}
return reverse( s, p - s );
}
int main(void)
{
char s[] = "5 60 +";
puts( s );
puts( reverse_by_words( s ) );
return 0;
}
The program output is
5 60 +
+ 60 5
If you want to keep leading and trailing spaces as they were in the original string then the functions can look the following way
#include <stdio.h>
#include <string.h>
static char *reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n - i -1 ];
s[n - i - 1] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t";
char *first = s, *last = s;
for ( char *p = s; *p; )
{
p += strspn( p, delim );
if ( last == s ) first = last = p;
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
last = p;
reverse( q, p - q );
}
}
reverse( first, last - first );
return s;
}
int main(void)
{
char s[] = "\t\t\t5 60 +";
printf( "\"%s\"\n", s );
printf( "\"%s\"\n", reverse_by_words( s ) );
return 0;
}
The program output is
" 5 60 +"
" + 60 5"

Reverse a string without strtok in C

Working on a program that uses RPN (Reverse Polish Notation).
I have a function that reverses all the words of string without using strtok or triggering printf (unlike all the solutions found online and here).
The function actually works partially as it prints all the words of a given string except the last one and I need help figuring out what's going on.
char *extract(char s[]) {
if (s[0] == '\0')
return NULL;
int i = 0;
char *p = NULL;
while (s[i] != '\0') {
if (s[i] == ' ')
p = s + i;
i++;
}
if (p != NULL) {
*p = '\0';
return p + 1;
}
}
And then it's called in main like this:
char s[MAX] = "5 60 +";
while(s != NULL){
printf("%s\n", extract(s));
}
The output is + 60 with the cursor endessly waiting for something
but the expected output should be + 60 5
A standard approach is to reverse each word within a string and then to reverse the whole string.
Here you are.
#include <stdio.h>
#include <string.h>
static char * reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[ i ];
s[ i ] = s[ n - i - 1 ];
s[ n - i - 1 ] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t";
char *p = s;
while ( *p )
{
p += strspn( p, delim );
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
reverse( q, p - q );
}
}
return reverse( s, p - s );
}
int main(void)
{
char s[] = "5 60 +";
puts( s );
puts( reverse_by_words( s ) );
return 0;
}
The program output is
5 60 +
+ 60 5
If you want to keep leading and trailing spaces as they were in the original string then the functions can look the following way
#include <stdio.h>
#include <string.h>
static char *reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n - i -1 ];
s[n - i - 1] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t";
char *first = s, *last = s;
for ( char *p = s; *p; )
{
p += strspn( p, delim );
if ( last == s ) first = last = p;
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
last = p;
reverse( q, p - q );
}
}
reverse( first, last - first );
return s;
}
int main(void)
{
char s[] = "\t\t\t5 60 +";
printf( "\"%s\"\n", s );
printf( "\"%s\"\n", reverse_by_words( s ) );
return 0;
}
The program output is
" 5 60 +"
" + 60 5"

Parsing a string to individual words

I'm looking at writing a function that parses a given string input and separates the string into its constituents (as defined by one or more space characters).
Unfortunately, I have had no real experience with string parsing, so any help would be really appreciated!
Many thanks!
Take a look to strsep(3) too, since it is "intended as a replacement for the strtok() function."
https://www.freebsd.org/cgi/man.cgi?strsep(3)
The function can be declared and defined the following way as it is shown in the demonstrative program.
#include <stdio.h>
#include <ctype.h>
size_t string_parser( const char *input, char *word_array[] )
{
size_t n = 0;
while ( *input )
{
while ( isspace( ( unsigned char )*input ) ) ++input;
if ( *input )
{
word_array[n++] = ( char * )input;
while ( *input && !isspace( ( unsigned char )*input ) ) ++input;
}
}
return n;
}
#define N 10
int main(void)
{
char s[] = "Hello Sam Talbot. How do you do?";
char * word_array[N];
size_t n = string_parser( s, word_array );
for ( size_t i = 0; i < n; i++ ) puts( word_array[i] );
return 0;
}
Its output is
Hello Sam Talbot. How do you do?
Sam Talbot. How do you do?
Talbot. How do you do?
How do you do?
do you do?
you do?
do?
Another approach to defining the function is to allocate dynamically the array of words inside the function. In this case the function declaration can look like
size_t string_parser( const char *input, char ***word_array )
You should at first count the words using one loop and then in another loop fill the array of words.
For example
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
size_t string_parser( const char *input, char ***word_array)
{
size_t n = 0;
const char *p = input;
while ( *p )
{
while ( isspace( ( unsigned char )*p ) ) ++p;
n += *p != '\0';
while ( *p && !isspace( ( unsigned char )*p ) ) ++p;
}
if ( n )
{
size_t i = 0;
*word_array = malloc( n * sizeof( char * ) );
p = input;
while ( *p )
{
while ( isspace( ( unsigned char )*p ) ) ++p;
if ( *p )
{
const char *q = p;
while ( *p && !isspace( ( unsigned char )*p ) ) ++p;
size_t length = p - q;
( *word_array )[i] = ( char * )malloc( length + 1 );
strncpy( ( *word_array )[i], q, length );
( *word_array )[i][length] = '\0';
++i;
}
}
}
return n;
}
int main(void)
{
char s[] = "Hello Sam Talbot. How do you do?";
char ** word_array = NULL;
size_t n = string_parser( s, &word_array );
for ( size_t i = 0; i < n; i++ ) puts( word_array[i] );
for ( size_t i = 0; i < n; i++ ) free( word_array[i] );
free( word_array );
return 0;
}
The program output is
Hello
Sam
Talbot.
How
do
you
do?
Take a look at strtok, this does what you require.
You need to at least attempt this on your own.

C source code to change first letters of words from lowercase to uppercase in a string

I have a C source code, but I have a problem with it. I want to convert the first letters of words in a string that I enter from lowercase to uppercase, but it changes all letters to uppercase. Can you help me solve this?
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
void main()
{
char sentence[100];
int count, ch, i;
int str[32];
printf("Enter a sentence \n");
for (i = 0; (sentence[i] = getchar()) != '\n'; i++)
{
;
}
sentence[i] = '\0';
/* shows the number of chars accepted in a sentence */
count = i;
printf("The given sentence is : %s", sentence);
printf("\n Case changed sentence is: ");
for (i = 0; i < count; i++)
{
ch = islower(sentence[i])? toupper(sentence[i]) : tolower(sentence[i]);
putchar(ch);
}
getch();
}
e.g.
Input: welcome to Sharif university
Desired output: Welcome To Sharif University
Actual output: WELCOME TO SHARIF UNIVERSITY
You must have check if the current char is a space and then only use toupper on the character after the space.
ch = ' ';
for (i = 0; i < count; i++)
{
ch = isspace(ch) ? toupper(sentence[i]) : tolower(sentence[i]);
putchar(ch);
}
Try the following code.:)
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
do
{
while ( isblank( ( unsigned char )*p ) ) ++p;
if ( islower( ( unsigned char )*p ) ) *p = toupper( *p );
while ( *p && !isblank( ( unsigned char )*p ) ) ++p;
} while ( *p );
printf( "\nCase changed sentence is: %s", sentence );
return 0;
}
The output is
The given sentence is : welcome to Sharif university
Case changed sentence is: Welcome To Sharif University
If yor compiler does not support function isblank then you can substitute it for isspace
It seems that a more correct approach will be to use only isalpha because in general case after a blank there can be for example a digit or punctuation
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
do
{
while ( *p && !isalpha( ( unsigned char )*p ) ) ++p;
if ( islower( ( unsigned char )*p ) ) *p = toupper( *p );
while ( isalpha( ( unsigned char )*p ) ) ++p;
} while ( *p );
printf( "\nCase changed sentence is: %s", sentence );
return 0;
}
If you do not want to change the original string then the code will look like
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
printf( "\nCase changed sentence is: " );
do
{
while ( *p && !isalpha( ( unsigned char )*p ) ) putchar( *p++ );
if ( islower( ( unsigned char )*p ) ) putchar( toupper( *p++ ) );
while ( isalpha( ( unsigned char )*p ) ) putchar( *p++ );
} while ( *p );
return 0;
}
You need to check for characters which have a space preceding them and upper case them. You also need to check for the first character which is a special case as it does not have a space preceding it.
#include <string.h>
#include <stdio.h>
int main (void)
{
char str[] = "this is a test string";
int loop;
for (loop=-1; loop<(int) strlen(str)-1; loop++)
{
// Possible upper case required?
if (loop < 0 || str[loop]==' ')
if (str[loop+1] >= 'a' && str[loop+1] <='z')
str[loop+1] = (str[loop+1] - 'a') + 'A';
}
printf ("string is : %s\n", str);
return 0;
}
Output:
string is : This Is A Test String

Resources