Convert String into Array of Strings in C - arrays

I'm trying to divide a string of alphabetically sorted words char *str = "a/apple/arm/basket/bread/car/camp/element/..."
into an array of strings alphabetically like so:
arr[0] = "a/apple/arm"
arr[1] = "basket/bread"
arr[2] = "car/camp"
arr[3] = ""
arr[4] = "element"
...
I'm not very skilled in C, so my approach was going to be to declare:
char arr[26][100];
char curr_letter = "a";
and then iterate over each char in the string looking for "/" follow by char != curr_letter, then strcpy that substring to the correct location.
I'm not sure if my approach is very good, let alone how to implement it properly.
Any help would be greatly appreciated!

So we basically loop through the string, and check if we found the "split character' and we also check that we didn't find the 'curr_letter' as the next character.
We keep track of the consumed length, the current length (used for memcpy later to copy the current string to the array).
When we find a position where we can add the current string to the array, we allocate space and copy the string to it as the next element in the array. We also add the current_length to consumed, and the current_length is reset.
We use due_to_end to find out if we have a / in the current string, and remove it accordingly.
Try:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char *str = "a/apple/arm/basket/bread/car/camp/element/...";
char split_char = '/';
char nosplit_char = 'a';
char **array = NULL;
int num_elts = 0;
// read all the characters one by one, and add to array if
// your condition is met, or if the string ends
int current_length = 0; // holds the current length of the element to be added
int consumed = 0; // holds how much we already added to the array
for (int i = 0; i < strlen(str); i++) { // loop through string
current_length++; // increment first
int due_to_end = 0;
if ( ( str[i] == split_char // check if split character found
&& ( i != (strlen(str) - 1) // check if its not the end of the string, so when we check for the next character, we don't overflow
&& str[i + 1] != nosplit_char ) ) // check if the next char is not the curr_letter(nosplit_char)
|| (i == strlen(str) - 1 && (due_to_end = 1))) { // **OR**, check if end of string
array = realloc(array, (num_elts + 1) * sizeof(char *)); // allocate space in the array
array[num_elts] = calloc(current_length + 1, sizeof(char)); // allocate space for the string
memcpy(array[num_elts++], str + consumed, (due_to_end == 0 ? current_length - 1 : current_length)); // copy the string to the current array offset's allocated memory, and remove 1 character (slash) if this is not the end of the string
consumed += current_length; // add what we consumed right now
current_length = 0; // reset current_length
}
}
for (int i = 0; i < num_elts; i++) { // loop through all the elements for overview
printf("%s\n", array[i]);
free(array[i]);
}
free(array);
}

Yes, the approach that you specify in your question seems good, in principle. However, I see the following problem:
Using strcpy will require a null-terminated source string. This means if you want to use strcpy, you will have to overwrite the / with a null character. If you don't want to have to modify the source string by writing null characters into it, then an alternative would be to use the function memcpy instead of strcpy. That way, you can specify the exact number of characters to copy and you don't require the source string to have a null terminating character. However, this also means that you will somehow have to count the number of characters to copy.
On the other hand, instead of using strcpy or memcpy, you could simply copy one character at a time from str into arr[0], until you encounter the next letter, and then copy one character at a time from str into arr[1], and so on. That solution may be simpler.
In accordance with the community guidelines for homework questions, I will not provide a full solution to your problem at this time.
EDIT: Since another answer has already provides a full solution which uses memcpy, I will now also provide a full solution, which uses the simpler solution mentioned above of copying one character at a time:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define NUM_LETTERS 26
#define MAX_CHARS_PER_LETTER 99
int main( void )
{
//declare the input string
char *str =
"a/apple/arm/basket/bread/car/camp/element/"
"frog/glass/saddle/ship/water";
//declare array which holds all the data
//we must add 1 for the terminating null character
char arr[NUM_LETTERS][MAX_CHARS_PER_LETTER+1];
//this variable will store the current letter that we
//have reached
char curr_letter = 'a';
//this variable will store the number of chars that are
//already used in the current letter, which will be a
//number between 0 and MAX_CHARS_PER_LETTER
int chars_used = 0;
//this variable stores whether the next character is
//the start of a new word
bool new_word = true;
//initialize the arrays to contain empty strings
for ( int i = 0; i < NUM_LETTERS; i++ )
arr[i][0] = '\0';
//read one character at a time
for ( const char *p = str; *p != '\0'; p++ )
{
//determine whether we have reached the end of a word
if ( *p == '/' )
{
new_word = true;
}
else
{
//determine whether we have reached a new letter
if ( new_word && *p != curr_letter )
{
//write terminating null character to string of
//previous letter, overwriting the "/"
if ( chars_used != 0 )
arr[curr_letter-'a'][chars_used-1] = '\0';
curr_letter = *p;
chars_used = 0;
}
new_word = false;
}
//verify that buffer is large enough
if ( chars_used == MAX_CHARS_PER_LETTER )
{
fprintf( stderr, "buffer overflow!\n" );
exit( EXIT_FAILURE );
}
//copy the character
arr[curr_letter-'a'][chars_used++] = *p;
}
//the following code assumes that the string pointed to
//by "str" will not end with a "/"
//write terminating null character to string
arr[curr_letter-'a'][chars_used] = '\0';
//print the result
for ( int i = 0; i < NUM_LETTERS; i++ )
printf( "%c: %s\n", 'a' + i, arr[i] );
}
This program has the following output:
a: a/apple/arm
b: basket/bread
c: car/camp
d:
e: element
f: frog
g: glass
h:
i:
j:
k:
l:
m:
n:
o:
p:
q:
r:
s: saddle/ship
t:
u:
v:
w: water
x:
y:
z:
Here is another solution which uses strtok:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_LETTERS 26
#define MAX_CHARS_PER_LETTER 99
int main( void )
{
//declare the input string
char str[] =
"a/apple/arm/basket/bread/car/camp/element/"
"frog/glass/saddle/ship/water";
//declare array which holds all the data
//we must add 1 for the terminating null character
char arr[NUM_LETTERS][MAX_CHARS_PER_LETTER+1];
//this variable will store the current letter that we
//have reached
char curr_letter = 'a';
//this variable will store the number of chars that are
//already used in the current letter, which will be a
//number between 0 and MAX_CHARS_PER_LETTER
int chars_used = 0;
//initialize the arrays to contain empty strings
for ( int i = 0; i < NUM_LETTERS; i++ )
arr[i][0] = '\0';
//find first token
char *p = strtok( str, "/" );
//read one token at a time
while ( p != NULL )
{
int len;
//determine whether we have reached a new letter
if ( p[0] != curr_letter )
{
curr_letter = p[0];
chars_used = 0;
}
//count length of string
len = strlen( p );
//verify that buffer is large enough to copy string
if ( chars_used + len >= MAX_CHARS_PER_LETTER )
{
fprintf( stderr, "buffer overflow!\n" );
exit( EXIT_FAILURE );
}
//add "/" if necessary
if ( chars_used != 0 )
{
arr[curr_letter-'a'][chars_used++] = '/';
arr[curr_letter-'a'][chars_used] = '\0';
}
//copy the word
strcpy( arr[curr_letter-'a']+chars_used, p );
//update number of characters used in buffer
chars_used += len;
//find next token
p = strtok( NULL, "/" );
}
//print the result
for ( int i = 0; i < NUM_LETTERS; i++ )
printf( "%c: %s\n", 'a' + i, arr[i] );
}

Related

Replacing words in a string with words given in a 2D array

I'm currently working on a program that corrects given words in a sentence to be more polite.
I'm building a function that is given the original sentence and a 2D array, that stores the words we should look for and the ones we will replace them with.
This is my main function where the "dictionary" is declared:
int main(){
const char * d1 [][2] =
{
{ "hey", "hello" },
{ "bro", "sir" },
{ NULL, NULL }
};
printf("%s\n", newSpeak("well hey bro", d1) );
}
This functions job is to go through every pointer of the original string and check it with the first character of each word, that could potentially be 'bad'. If it catches the first letter, then it will go through the rest of the word and if it goes all the way to the end of the word, it will skip the original word and replace it with the 'good' word.
This is the function itself:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
char * newSpeak ( const char * text, const char * (*replace)[2] )
{
char * result = (char*)malloc( sizeof(char) );
int resIndex = 0; // Pointer to final text
int matches = 0; // 1 - Matches word from library, 0 - Does not
// Run through the whole original text
for ( int index = 0; text[index] != '\0'; index++ ){
for ( int line = 0; replace[line][0] != NULL; line++ ){
// If the first letter of the word matches, do the others match too?
// If yes, don't rewrite the original word, skip it, and write the replacement one by one.
if ( replace[line][0][0] == text[index] ){
matches = 1;
// Check one by one if letters from the word align with letters in the original string
for ( int letter = 0; replace[line][0][letter] != '\0'; letter++ ){
if ( replace[line][0][letter] != text[index + letter] ){
matches = 0;
break;
}
}
// If the whole word matches, skip what would be copied from original text (the bad word) and put in replacement letter by letter
if ( matches == 1 ){
// Push pointer of original string after the word
index += strlen( replace[line][0] );
for ( int r = 0; r < strlen( replace[line][1] ); r++){
result = (char*)realloc(result, (strlen( result ) + 1) * sizeof(char));
result[resIndex + r] = replace[line][1][r];
index += r;
}
}
}
}
if ( matches == 0 ){
result = (char*)realloc(result, (strlen( result ) + 1) * sizeof(char));
result[resIndex] = text[index];
}
resIndex++;
}
return result;
}
After this is run, my expected outcome is well hello sir, but instead, the function only returns well hello.
I am looking for an explanation to why the loop would stop and not check for the rest of the string, any help would be appreciated.
At least this problem:
strlen( result ) in result = (char*)realloc(result, (strlen( result ) + 1) * sizeof(char)); is not valid as result does not point to a string. Missing null character.

Swap words of a string without using sting library and use pointers

The goal of my exercise is to produce
The original string is:
silence .is a looking bird:the turning; edge, of life. e. e. cummings
Destination string after swapping:
cummings e. e. life. of edge, turning; bird:the looking a .is silence
and what I am getting is:
69The original string is:
silence .is a looking bird:the turning; edge, of life. e. e. cummings
Destination string after swapping:
my code:
'''
#include<stdio.h>
#include<stdlib.h>
#define MAX_STR_LEN 1024
// DO NOT USE the string library <string.h> for this exercise
void wordSwapper(char *source, char *destination)
{
int count = 0;
while (*(source + count) != '\0')
{
count++;
}
printf("%d", count);
for(int i = 0; i < count; i++)
{
*(destination + i) = *(source + (count - i));
}
}
int main()
{
char source[MAX_STR_LEN]="silence .is a looking bird:the turning; edge, of life. e. e. cummings";
char destination[MAX_STR_LEN]="I am a destination string and I contain lots of junk 1234517265716572#qsajdkuhasdgsahiehwjauhiuiuhdsj!";
wordSwapper(&source[0], &destination[0]);
printf("The original string is: \n%s\n",source);
printf("Destination string after swapping: \n%s\n",destination);
}
'''
My variant:
void wordSwapper(char *source, char *destination)
{
char *start, *end;
start = source;
while (*(start++) != '\0')
destination++;
// write trailing zero
*destination = '\0';
while (*source != '\0')
{
// copy spaces
while (*source == ' ')
*(--destination) = *(source++);
// find word bounds
start = end = source;
while (*end != '\0' && *end != ' ')
end++;
source = end;
// copy word
while (end > start)
*(--destination) = *(--end);
}
}
The posted code reverse the string - character by character. Two issues:
off-by-one, where the terminating NUL character is copied to position 0 of the destination string, therefore the result is empty string. The sec
The requirement is to split the string into words, and copy the words in reverse order to the destination string.
Consider the following alternative
void wordSwapper2(char *source, char *destination)
{
int count = 0;
while (*(source + count) != '\0')
{
count++;
}
// Copy words in reverse order
char *dest = destination ;
int dest_pos = 0 ;
// Word End
int w_end = count ;
while ( w_end >= 0 ) {
// Find word start
int w_start = w_end ;
while ( w_start > 0 && source[w_start-1] != ' ' ) w_start-- ;
// Copy word
for (int i=w_start ; i<w_end ; i++ ) *dest++ = source[i] ;
// Add space if not first word
if ( w_start > 0 ) *dest++ = ' ' ;
// Move to previous word (skip over space)
w_end = w_start-1 ;
} ;
// Terminating NUL
*dest++ = '\0' ;
}

I need help understanding the code for reversing a string

I need help understanding a function for reversing the array of string.
I have been looking through a few codes, and just trying to understand it. It is a function using a pointer.
void ReverseString(char *pStr){
int length = 0;
int i = 0;
while(pStr[i]!='\0')
{
length++;
i++;
}
for (int i = 0; i < length / 2; i++) {
char temp = pStr[length - i - 1] ;
pStr[length - i - 1] = pStr[i];
pStr[i] = temp;
}
}
I am expecting it to reverse a string; I have a main function that uses it.
Strings in C are sequences of characters terminated with a zero character '\0'.
So this loop
while(pStr[i]!='\0')
{
length++;
i++;
}
calculates the length of the string that is how many characters there are in the string before the zero character. Instead of the loop you could use standard C function strlen declared in header <string.h>.
This loop
for (int i = 0; i < length / 2; i++) {
char temp = pStr[length - i - 1] ;
pStr[length - i - 1] = pStr[i];
pStr[i] = temp;
}
swaps character from the first half of the string with characters of the second half of the string. That is the first character is swapped with the last character, the second character is swapped with the before last character and so on until the middle of the string.
The function has several drawbacks. It could be written (without using standard C functions) the following way
#include <stdio.h>
char * ReverseString( char *pStr )
{
size_t n = 0;
// Calculates the number of characters in the string
// excluding the zero character.
// SO the variable n will contain the number of characters in the string.
while ( pStr[n] != '\0' ) ++n;
// Swaps characters from the first half of the string with
// the characters of the second half of the string.
// So the loop has only n / 2 iterations.
for ( size_t i = 0; i < n / 2; i++ )
{
char c = pStr[n - i - 1] ;
pStr[n - i - 1] = pStr[i];
pStr[i] = c;
}
return pStr;
}
int main( void )
{
char s[] = "Prachi Rajesh Jansari";
puts( s );
puts( ReverseString( s ) );
}
The program output is
Prachi Rajesh Jansari
irasnaJ hsejaR ihcarP

Reversing a string without using any libraries

Now I want to implement a function to "reverse" a given string. My idea was not to swap, rather I thought of declaring a new array in the implemented function to absorb the new string in its reversed state.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
void reverseString( char string[ ], int size );
int main()
{
char string[ 14 ] = "reverse me";
printf( "The string is: %s\n", string );
reverseString( string, 14 );
return 0;
}
void reverseString( char string[ ], int size )
{
int i, j;
char newString[ size ];
for( ( i = ( size ) ) & ( j = 0 ); ( i >= 0 ) && ( j < ( size ) ); i-- & j ++ )
{
newString[ j ] = string[ i ];
}
printf( "\nThe string reversed: %s\n", newString );
}
could anybody please help me to get the idea of reversing strings? Was I approaching the idea when looking at my code or what ?!
function reverseString(string) {
var splitedString = string.split("");
var reverseArray = splitedString.reverse();
var joinArray = reverseArray.join("");
return joinArray;
}
var newString = reverseString("hello");
console.log(newString);
Are you expecting something like this?
A String can be referred to as an array of characters with a null character '\0' at the end of it. If a string is "Banana", then actually the compiler treats it as "Banana\0". When dealing with strings in the program, you have to remember to append the null character to the string that you create.
Here is the working code for the same -
#include <stdio.h>
int main()
{
char string[10] = "banana";
char reverse[10];
int start, end, length = 0;
// Calculating string length - to be used when length is not already known
/*while (string[length] != '\0')
length++;*/
//in this case
length=10;
end = length - 1; /*this is done because indexing in arrays and strings starts
at 0, not at 1...so string[0] gives first character of the
string and string[size-1] gives the last character of the
string*/
for (start = 0; start < length; start++)
{
reverse[start] = string[end];
end--;
}
reverse[start] = '\0'; //here we add the null character to the end of the string
printf("%s\n", reverse);
return 0;
}
Looking at your code, your idea was correct. You just need to brush up some concepts like String indexing, Null character in strings etc.
The same thing can be done using library functions as well.

C - Largest String From a Big One

So pray tell, how would I go about getting the largest contiguous string of letters out of a string of garbage in C? Here's an example:
char *s = "(2034HEY!!11 th[]thisiswhatwewant44";
Would return...
thisiswhatwewant
I had this on a quiz the other day...and it drove me nuts (still is) trying to figure it out!
UPDATE:
My fault guys, I forgot to include the fact that the only function you are allowed to use is the strlen function. Thus making it harder...
Uae strtok() to split your string into tokens, using all non-letter characters as delimiters, and find the longest token.
To find the longest token you will need to organise some storage for tokens - I'd use linked list.
As simple as this.
EDIT
Ok, if strlen() is the only function allowed, you can first find the length of your source string, then loop through it and replace all non-letter characters with NULL - basically that's what strtok() does.
Then you need to go through your modified source string second time, advancing one token at a time, and find the longest one, using strlen().
This sounds similar to the standard UNIX 'strings' utility.
Keep track of the longest run of printable characters terminated by a NULL.
Walk through the bytes until you hit a printable character. Start counting. If you hit a non-printable character stop counting and throw away the starting point. If you hit a NULL, check to see if the length of the current run is greater then the previous record holder. If so record it, and start looking for the next string.
What defines the "good" substrings compared to the many others -- being lowercase alphas only? (i.e., no spaces, digits, punctuation, uppercase, &c)?
Whatever the predicate P that checks for a character being "good", a single pass over s applying P to each character lets you easily identify the start and end of each "run of good characters", and remember and pick the longest. In pseudocode:
longest_run_length = 0
longest_run_start = longest_run_end = null
status = bad
for i in (all indices over s):
if P(s[i]): # current char is good
if status == bad: # previous one was bad
current_run_start = current_run_end = i
status = good
else: # previous one was also good
current_run_end = i
else: # current char is bad
if status == good: # previous one was good -> end of run
current_run_length = current_run_end - current_run_start + 1
if current_run_length > longest_run_length:
longest_run_start = current_run_start
longest_run_end = current_run_end
longest_run_length = current_run_length
status = bad
# if a good run ends with end-of-string:
if status == good: # previous one was good -> end of run
current_run_length = current_run_end - current_run_start + 1
if current_run_length > longest_run_length:
longest_run_start = current_run_start
longest_run_end = current_run_end
longest_run_length = current_run_length
Why use strlen() at all?
Here's my version which uses no function whatsoever.
#ifdef UNIT_TEST
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
/*
// largest_letter_sequence()
// Returns a pointer to the beginning of the largest letter
// sequence (including trailing characters which are not letters)
// or NULL if no letters are found in s
// Passing NULL in `s` causes undefined behaviour
// If the string has two or more sequences with the same number of letters
// the return value is a pointer to the first sequence.
// The parameter `len`, if not NULL, will have the size of the letter sequence
//
// This function assumes an ASCII-like character set
// ('z' > 'a'; 'z' - 'a' == 25; ('a' <= each of {abc...xyz} <= 'z'))
// and the same for uppercase letters
// Of course, ASCII works for the assumptions :)
*/
const char *largest_letter_sequence(const char *s, size_t *len) {
const char *p = NULL;
const char *pp = NULL;
size_t curlen = 0;
size_t maxlen = 0;
while (*s) {
if ((('a' <= *s) && (*s <= 'z')) || (('A' <= *s) && (*s <= 'Z'))) {
if (p == NULL) p = s;
curlen++;
if (curlen > maxlen) {
maxlen = curlen;
pp = p;
}
} else {
curlen = 0;
p = NULL;
}
s++;
}
if (len != NULL) *len = maxlen;
return pp;
}
#ifdef UNIT_TEST
void fxtest(const char *s) {
char *test;
const char *p;
size_t len;
p = largest_letter_sequence(s, &len);
if (len && (len < 999)) {
test = malloc(len + 1);
if (!test) {
fprintf(stderr, "No memory.\n");
return;
}
strncpy(test, p, len);
test[len] = 0;
printf("%s ==> %s\n", s, test);
free(test);
} else {
if (len == 0) {
printf("no letters found in \"%s\"\n", s);
} else {
fprintf(stderr, "ERROR: string too large\n");
}
}
}
int main(void) {
fxtest("(2034HEY!!11 th[]thisiswhatwewant44");
fxtest("123456789");
fxtest("");
fxtest("aaa%ggg");
return 0;
}
#endif
While I waited for you to post this as a question I coded something up.
This code iterates through a string passed to a "longest" function, and when it finds the first of a sequence of letters it sets a pointer to it and starts counting the length of it. If it is the longest sequence of letters yet seen, it sets another pointer (the 'maxStringStart' pointer) to the beginning of that sequence until it finds a longer one.
At the end, it allocates enough room for the new string and returns a pointer to it.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int isLetter(char c){
return ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') );
}
char *longest(char *s) {
char *newString = 0;
int maxLength = 0;
char *maxStringStart = 0;
int curLength = 0;
char *curStringStart = 0;
do {
//reset the current string length and skip this
//iteration if it's not a letter
if( ! isLetter(*s)) {
curLength = 0;
continue;
}
//increase the current sequence length. If the length before
//incrementing is zero, then it's the first letter of the sequence:
//set the pointer to the beginning of the sequence of letters
if(curLength++ == 0) curStringStart = s;
//if this is the longest sequence so far, set the
//maxStringStart pointer to the beginning of it
//and start increasing the max length.
if(curLength > maxLength) {
maxStringStart = curStringStart;
maxLength++;
}
} while(*s++);
//return null pointer if there were no letters in the string,
//or if we can't allocate any memory.
if(maxLength == 0) return NULL;
if( ! (newString = malloc(maxLength + 1)) ) return NULL;
//copy the longest string into our newly allocated block of
//memory (see my update for the strlen() only requirement)
//and null-terminate the string by putting 0 at the end of it.
memcpy(newString, maxStringStart, maxLength);
newString[maxLength + 1] = 0;
return newString;
}
int main(int argc, char *argv[]) {
int i;
for(i = 1; i < argc; i++) {
printf("longest all-letter string in argument %d:\n", i);
printf(" argument: \"%s\"\n", argv[i]);
printf(" longest: \"%s\"\n\n", longest(argv[i]));
}
return 0;
}
This is my solution in simple C, without any data structures.
I can run it in my terminal like this:
~/c/t $ ./longest "hello there, My name is Carson Myers." "abc123defg4567hijklmnop890"
longest all-letter string in argument 1:
argument: "hello there, My name is Carson Myers."
longest: "Carson"
longest all-letter string in argument 2:
argument: "abc123defg4567hijklmnop890"
longest: "hijklmnop"
~/c/t $
the criteria for what constitutes a letter could be changed in the isLetter() function easily. For example:
return (
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c == '.') ||
(c == ' ') ||
(c == ',') );
would count periods, commas and spaces as 'letters' also.
as per your update:
replace memcpy(newString, maxStringStart, maxLength); with:
int i;
for(i = 0; i < maxLength; i++)
newString[i] = maxStringStart[i];
however, this problem would be much more easily solved with the use of the C standard library:
char *longest(char *s) {
int longest = 0;
int curLength = 0;
char *curString = 0;
char *longestString = 0;
char *tokens = " ,.!?'\"()#$%\r\n;:+-*/\\";
curString = strtok(s, tokens);
do {
curLength = strlen(curString);
if( curLength > longest ) {
longest = curLength;
longestString = curString;
}
} while( curString = strtok(NULL, tokens) );
char *newString = 0;
if( longest == 0 ) return NULL;
if( ! (newString = malloc(longest + 1)) ) return NULL;
strcpy(newString, longestString);
return newString;
}
First, define "string" and define "garbage". What do you consider a valid, non-garbage string? Write down a concrete definition you can program - this is how programming specs get written. Is it a sequence of alphanumeric characters? Should it start with a letter and not a digit?
Once you get that figured out, it's very simple to program. Start with a naive method of looping over the "garbage" looking for what you need. Once you have that, look up useful C library functions (like strtok) to make the code leaner.
Another variant.
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[] = "(2034HEY!!11 th[]thisiswhatwewant44";
int len = strlen(s);
int i = 0;
int biggest = 0;
char* p = s;
while (p[0])
{
if (!((p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z')))
{
p[0] = '\0';
}
p++;
}
for (; i < len; i++)
{
if (s[i] && strlen(&s[i]) > biggest)
{
biggest = strlen(&s[i]);
p = &s[i];
}
}
printf("%s\n", p);
return 0;
}

Resources