sorting letters in a string with double pointer - c

I'm stuck with sorting letters in a string. It must be sorted in alphabetical order using double pointers.
#define SIZE 21 //defined index of the array
int _tmain(int argc, _TCHAR* argv[])
{
// an array with 21 strings
char * string[SIZE] = { "dfghgfd", "rtyukljgfds", "sdsf", "fdgdfhg", "fgfhgjghj", "nmjlkjlk", "qwasazx",
"zxdfd", "opiljkg", "vcxdfgfd", "fgfhgfhgh", "bvvh", "bb", "dfsdretr",
"reuio", "cvbmhg", "fgfdyrtyty", "fgdgdfgdfgdf", "g", "fgdfg", "ghghgfhv" };
-----------------------Access to each string in array ------------------------
int Anz, i; //Anz - 21 strings
//declared new array
char** new_string;
new_string = (char**)malloc(sizeof(string));
Anz = sizeof(string) / sizeof(char*);
for (i = 0; i < Anz; i++)
{
new_string[i] = (char*)malloc(strlen(string[i]) + 1);
strcpy(new_string[i], string[i]);
}
----------------------- sorting letters--------------------------------------
char* temp;
int k, j;
for (k = 0; k<Anz - 1; k++)
{
for (j = k + 1; j<Anz; j++)
{
if (new_string[k] > new_string[j])
{
temp = new_string[k];
new_string[k] = new_string[j];
new_string[j] = temp;
}
}
}
return 0;
}

Not sure why you need the "a" array, since you can swap the characters using the new string array. Also, using a char * to hold the length of values is sort weird but I guess it works since the string lengths are pretty short.

Not sure if you wanted to sort the letters or the words. A commented section sorts the words.
Check the return of malloc as it can fail.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 21 //defined index of the array
int main(int argc, char** argv)
{
// an array with 21 strings
char * string[SIZE] = { "dfghgfd", "rtyukljgfds", "sdsf", "fdgdfhg", "fgfhgjghj", "nmjlkjlk", "qwasazx",
"zxdfd", "opiljkg", "vcxdfgfd", "fgfhgfhgh", "bvvh", "bb", "dfsdretr",
"reuio", "cvbmhg", "fgfdyrtyty", "fgdgdfgdfgdf", "g", "fgdfg", "ghghgfhv" };
int Anz, i; //Anz - 21 strings
int width = 0, len = 0;
//declared new array
char** new_string;
Anz = sizeof(string) / sizeof(*string);
if ( NULL == ( new_string = malloc ( Anz * sizeof( *new_string)))) {
fprintf ( stderr, "malloc failed\n");
return 0;
}
for (i = 0; i < Anz; i++)
{
len = strlen ( string[i]) + 1;
if ( len > width) {
width = len;//used later when printing
}
if ( NULL == ( new_string [i] = malloc ( width))) {
fprintf ( stderr, "[i] malloc failed\n");
//free memory allocated
while ( i) {
i--;
free ( new_string[i]);
}
free ( new_string);
return 0;
}
strcpy(new_string[i], string[i]);
}
/*
//sort words
int word = 0;
while ( word < Anz - 1) {
int end = word;
int temp = end + 1;
while ( end >= 0 && 0 > strcmp ( new_string[temp], new_string[end])) {
char *hold = new_string[temp];
new_string[temp] = new_string[end];
new_string[end] = hold;
end--;
temp--;
}
word++;
}
word = 0;
while ( word < Anz) {
printf ( "Anz[%2d] is %s\n", word, new_string[word]);
word++;
}
*/
//sort letters in word
char swap;
int sorted;
int prior;
int each;
int start;
word = 0;
while ( word < Anz)
{
start = 0;//new_string[Anz][0]
sorted = start;
prior = start;
each = start + 1;//new_string[Anz][1]
printf ( "Anz[%2d] is %-*s", word, width, new_string[word]);
while ( '\0' != new_string[word][each]) {
while ( prior >= 0 && new_string[word][each] < new_string[word][prior]) {
swap = new_string[word][each];
new_string[word][each] = new_string[word][prior];
new_string[word][prior] = swap;
each--;//move toward start of string
prior--;
}
sorted++;//move toward end of string
prior = sorted;
each = prior + 1;
}
printf ( " sorted %s\n", new_string[word]);
word++;
}
//release allocated memory
word = 0;
while ( word < Anz) {
free ( new_string[word]);
word++;
}
free ( new_string);
return 0;
}

Related

How modify a multidimensional pointer inside a function?

I have a function that manipulates a char*** using malloc and memcpy this way
// Convert a buffer full line to separated variables
int parseBufferToVariables(char ***variableContainer, char *bufferToParse, int maxVarSize) {
int i = 0;
// Get number of rows of the string
int numberOfRows = 0;
for (i = 0; bufferToParse[i] != '\0'; i++) {
if (bufferToParse[i] == '\n')
++numberOfRows;
}
// Get number of columns of the string
int numberOfColumns = 1;
for (i = 0; bufferToParse[i] != '\n'; i++) {
if (bufferToParse[i] == '\t')
++numberOfColumns;
}
// Allocate separated variable array
size_t dim0 = numberOfColumns, dim1 = numberOfRows, dim2 = maxVarSize;
variableContainer = malloc(sizeof *variableContainer * dim0);
if (variableContainer) {
size_t i;
for (i = 0; i < dim0; i++) {
variableContainer[i] = malloc(sizeof *variableContainer[i] * dim1);
if (variableContainer[i]) {
size_t j;
for (j = 0; j < dim1; j++) {
variableContainer[i][j] = malloc(sizeof *variableContainer[i][j] * dim2);
}
}
}
}
// Start parsing string to 3D array
int init = 0;
int numberOfVars = 0;
int numberOfLines = 0;
int sizeOfVar = 0;
int position = 0;
char emptyArray[MAXVARSIZE] = {0};
// Loop trought all lines
i = 0;
while (numberOfLines < numberOfRows) {
// Every delimiter
if (bufferToParse[i] == '\t' || bufferToParse[i] == '\n') {
// Size of the new sring
sizeOfVar = i - init;
// Set last \0 character in order to recognize as a proper string
memcpy(&variableContainer[numberOfVars][numberOfLines], emptyArray, maxVarSize);
// Copy the string to array
memcpy(&variableContainer[numberOfVars][numberOfLines], &bufferToParse[position], sizeOfVar);
// Handle pointers poisition
init = i + 1;
position += sizeOfVar + 1;
// Handle when end of line is reached
if (bufferToParse[i] == '\n') {
numberOfVars = 0;
numberOfLines++;
}
}
i++;
}
return numberOfRows;
}
And Im trying to call it in different ways:
char*** container= {0};
parseBufferToVariables (&container, inputString, MAXVARSIZE);
char*** container= {0};
parseBufferToVariables (container, inputString, MAXVARSIZE);
Even I try calling a char**** in the function:
int parseBufferToVariables(char**** variableContainer, char* bufferToParse, int maxVarSize)
But I always have a seg-fault calling the char*** outside the parseBufferToVariables function.
Any ideas?
OP is shooting for a 4 * parameter, yet other approaches are better.
The high degree of *s mask a key failing is that code needs to convey the column (# of tabs) width somehow.
Further, I see no certain null character termination in forming the _strings_as
the 2nd memcpy() is unbounded in size - may even overwrite allocation boundaries.
The idea below is that each level of allocation ends with a null.
csv = parse_file_string(const char *file_string);
Upon return, when csv[line] == NULL, there are no more lines
When csv[line][tab] == NULL, there are no more strings.
This approach also allows for a different number of strings per line.
Adjusted algorithm, pseudo C code
// return NULL on error
char ***parse_file_string(const char *file_string) {
number_lines = find_line_count(file_string);
char ***csv = calloc(number_lines + 1, sizeof *csv);
if (csv == NULL) return NULL;
for (line=0; line < number_lines; line++) {
tab_count = find_tab_count(file_string);
csv[line] = calloc(tab_count + 2, sizeof *(csv[line]));
// add NULL check
for (tab=0; tab < tab_count; tab++) {
char *end = strchr(file_string, '\t');
csv[line][tab] = malloc_string(file_string, end);
// add NULL check
file_string = end + 1;
}
char *end = strchr(file_string, '\n');
csv[line][tab++] = malloc_str(file_string, end);
// add NULL check
file_string = end + 1;
csv[line][tab] = NULL;
}
csv[line] = NULL;
return csv;
}
Usage
char ***container = parse_file_string(file_string);
for (line=0; container[line]; line++)
for (tab=0; container[line][tab]; tab++)
puts(container[line][tab]);
//free
for (line=0; container[line]; line++)
for (tab=0; container[line][tab]; tab++)
free(container[line][tab]);
free(container[line]);
free (container)
A pointer to a variable length array could be used if supported.
First get the dimensions of the contents of the buffer. This assumes that each line will have the same number of tabs.
Declare the pointer and allocate the memory.
Then parse the buffer into the allocated memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void getdimension ( char *buffer, int *rows, int *cols, int *size) {
int maxsize = 0;
*rows = 0;
*cols = 0;
*size = 0;
while ( *buffer) {//not the terminating zero
if ( '\n' == *buffer) {
if ( ! *rows) {//no rows counted yet
++*cols;//add a column
}
++*rows;
if ( maxsize > *size) {
*size = maxsize;
}
maxsize = 0;
}
if ( '\t' == *buffer) {
if ( ! *rows) {//no rows counted yet
++*cols;
}
if ( maxsize > *size) {
*size = maxsize;
}
maxsize = 0;
}
++maxsize;
++buffer;
}
if ( '\n' != *(buffer - 1)) {//last character is not a newline
++*rows;
if ( maxsize > *size) {
*size = maxsize;
}
}
}
void createptr ( int rows, int columns, int size, char (**ptr)[columns][size]) {
if ( NULL == ( *ptr = malloc ( sizeof **ptr * rows))) {
fprintf ( stderr, "malloc problem\n");
exit ( EXIT_FAILURE);
}
for ( int line = 0; line < rows; ++line) {
for ( int tab = 0; tab < columns; ++tab) {
(*ptr)[line][tab][0] = 0;
}
}
}
void parsebuffer ( char *buffer, int rows, int columns, int size, char (*ptr)[columns][size]) {
int eachrow = 0;
int eachcol = 0;
int eachsize = 0;
while ( *buffer) {
if ( '\n' == *buffer) {
++eachrow;
eachcol = 0;
eachsize = 0;
}
else if ( '\t' == *buffer) {
++eachcol;
eachsize = 0;
}
else {
ptr[eachrow][eachcol][eachsize] = *buffer;
++eachsize;
ptr[eachrow][eachcol][eachsize] = 0;
}
++buffer;
}
}
int main ( void) {
char line[] = "12\t34\t56\t78\t!##\n"
"abc\tdef\tghi\tjkl\t$%^\n"
"mno\tpqr\tstu\tvwx\tyz\n"
"ABC\tDEF\tGHI\tJKL\tMNOPQ\n";
int rows = 0;
int columns = 0;
int size = 0;
getdimension ( line, &rows, &columns, &size);
printf ( "rows %d cols %d size %d\n", rows, columns, size);
char (*ptr)[columns][size] = NULL;//pointer to variable length array
createptr ( rows, columns, size, &ptr);
parsebuffer ( line, rows, columns, size, ptr);
for ( int row = 0; row < rows; ++row) {
for ( int col = 0; col < columns; ++col) {
printf ( "ptr[%d][%d] %s\n", row, col, ptr[row][col]);
}
}
free ( ptr);
return 0;
}

C - Split Slows Down My Computer

I'm trying to program a split that takes in a char-array with multiple words and separates each word into their own smaller char-array. All the pointers of the smaller char-arrays are kept in a pointer array so I can return a double pointer.
Can you take a look at my code and see if you see any errors. When I try to run my program my computer gets gradually slower, after 3-4 seconds I can't move my mouse or alt+f4 my editor. So something has to be seriously wrong!
Also I'm completely new to C-programming so I will most definitely have a silly mistake in there.
char **split(char *s) {
char **result;
int wrd_cnt = 2; //I'm adding NULL at the end of the pointer-array.
//Counts the number of words to allocate memory for the pointer-array.
for(int i = 0; i < strlen(s); i++) {
if(s[i] == ' ') {
wrd_cnt++;
}
}
result = malloc(wrd_cnt * sizeof(char*));
//Counts letters in each word to allocate memory for every single small char-array with malloc.
for(int i = 0; i < strlen(s); i++) {
for(int j = 0; j < (wrd_cnt); j++) {
int char_cnt = 0;
for(int k = 0; s[i] != ' ' || s[i] != '\0'; k++, i++) {
char_cnt++;
result[j] = malloc(char_cnt * sizeof(char));
}
}
}
//Puts each word into their own place in the pointer array.
for(int i = 0; i < strlen(s); i++) {
for(int j = 0; j < (wrd_cnt); j++) {
for(int k = 0; s[i] != ' ' || s[i] != '\0'; k++, i++) {
result[j][k] = s[i];
}
}
}
result[wrd_cnt-1] = NULL;
return result;
}
In this situation the loops using j and k can be removed and instead increment and reset i, j and char_cnt based on the i loop as the s array is processed, similar to what you had done for wrd_cnt in the first loop
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char **split(char *s);
int main ( void) {
char **output = NULL;
int each = 0;
char line[99] = " string to parse for words ";
output = split ( line);
each = 0;
while ( output[each]) {
printf ( "%s\n", output[each]);
each++;
}
each = 0;
while ( output[each]) {
free ( output[each]);
each++;
}
free ( output);
exit ( 0);
}
char **split(char *s) {
char **result;
int wrd_cnt = 2; //I'm adding NULL at the end of the pointer-array.
int char_cnt = 0;
int i = 0;
int j = 0;
int k = 0;
//Counts the number of words to allocate memory for the pointer-array.
for(i = 0; i < strlen(s); i++) {
if(s[i] == ' ') {
wrd_cnt++;
}
}
if ( ( result = malloc(wrd_cnt * sizeof(char*))) == NULL) {
fprintf ( stderr, "malloc failure\n");
exit ( 1);
}
//Counts letters in each word to allocate memory for every single small char-array with malloc.
char_cnt = 1;
j = 0;
for( i = 0; i < strlen(s); i++) {
if ( s[i] == ' ') {
if ( ( result[j] = malloc(char_cnt * sizeof(char))) == NULL) {
fprintf ( stderr, "malloc failure\n");
exit ( 1);
}
j++;
char_cnt = 1;
continue;
}
char_cnt++;
}
if ( j == wrd_cnt - 2) {
//allocate for last word
if ( ( result[j] = malloc(char_cnt * sizeof(char))) == NULL) {
fprintf ( stderr, "malloc failure\n");
exit ( 1);
}
j++;
result[j] = NULL;
}
result[wrd_cnt - 1] = NULL;//just to make sure the last pointer is null
//Puts each word into their own place in the pointer array.
j = 0;
k = 0;
for( i = 0; i < strlen(s); i++) {
if ( s[i] == ' ') {
result[j][k] = '\0';//for space only so [j][0] is '\0'
k = 0;
j++;
continue;
}
result[j][k] = s[i];
k++;
result[j][k] = '\0';//for last word if there is no final space in s[]
}
return result;
}
Aside from the comments above your code scares me because of all the malloc() calls you do, one for each word. This means you must also free each word. This leaves programs open to memory leaks.
Given that this is C, which allows lots of casting, you can use a single malloc to hold both the (char *) pointer array AND the actual words.
char **split(char const *s) {
char **result; //
char *target; // where in result chars stored
size_t s_strlen = strlen(s); // length of s
int wrd_cnt = 2; //I'm adding NULL at the end of the pointer-array.
{
char const *sx;
for ( sx = s; sx = strpbrk( sx, " \t\n\r" ); sx++ )
{
wrd_cnt++;
}
}
result = malloc( (wrd_cnt * sizeof(char *)) + s_strlen + 2 );
/* allow for \0 and possible ' ' */
target = (char *)(result + wrd_cnt); /* where to save words */
strcpy( target, s ); /* copy to target known to be big enough */
if ( s_strlen > 0 && target[s_strlen-1] != ' ' )
strcat( target + s_strlen, " " ); /* assure ends in space */
{
char *tx, *tnext;
int n;
n = 0;
for ( tx = target; tnext = strpbrk( tx, " \t\n\r" ); tx = tnext + 1 )
{
result[n++] = tx; /* remember pointer */
*tnext = '\0'; /* terminate word */
}
result[n] = NULL; /* null termination */
}
return result;
}

Inserting a value into an array and arranging array according to value c

char num = '5';
strcpy(array, "2,3,7,9")
Hi guys, any ideas if want to insert 5 into the array according to the value which will result in, how would i go about doing this?
array = "2,3,5,7,9"
#include <stdio.h>
#include <string.h>
void insert_string(char *target, const char *to_insert, int index) {
int count = 0;
int i;
int move_dst;
int insert_comma = 0;
int to_len = strlen(to_insert);
if (index < 0) index = 0;
if (index <= 0) {
i = 0;
} else {
for (i = 0; target[i] != '\0'; i++) {
if (target[i] == ',') {
count++;
if (count >= index) {
i++;
break;
}
}
}
}
/* i is where to insert the string */
if (target[i] == '\0') {
/* the insertion target was end of the string */
target[i] = ',';
target[++i] = '\0';
}
move_dst = i + to_len;
if (target[i] != '\0') {
/* the sequence continues after insertion point */
move_dst++;
insert_comma = 1;
}
memmove(&target[move_dst], &target[i], strlen(&target[i]) + 1); /* copy includes termination '\0' */
memcpy(&target[i], to_insert, to_len);
if (insert_comma) target[i + to_len] = ',';
}
int main(void) {
char array[1024];
char num = '5';
char num_string[2] = {num, '\0'};
int c = 2;
strcpy(array, "2,3,7,9");
puts(array);
insert_string(array, num_string, c);
puts(array);
return 0;
}

When the string is number C language

I want to return nothing when the string is number
here is my code,
#include <string.h>
#include <ctype.h>
int num = 0;
char* findWord(char* subString) {
char* word = malloc(sizeof(char) * (strlen(subString) + 1));
int i = 0;
int Position = 0;
num = 0;
while (ispunct(subString[i]) != 0 || isspace(subString[i]) != 0) {
i++;
}
num = i;
while (ispunct(subString[i]) == 0 && isspace(subString[i]) == 0) {
word[Position] = subString[i];
i++;
Position++;
}
word[Position] = '\0';
return word;
}
char** wordList(const char* s) {
int len = strlen(s);
int i = 0;
char* Copyword = malloc(sizeof(char) * len);
strncpy(Copyword, s, len);
char** result = (char**) malloc(sizeof(char*) * (len + 1));
char* word = NULL;
word = findWord(Copyword);
char* wordEnd = Copyword;
while (*word != 0) {
result[i] = word;
wordEnd = wordEnd + strlen(word) + num;
word = findWord(wordEnd);
i++;
}
result[i] = '\0';
free(Copyword);
return result;
}
int main(void) {
char** words = wordList("1 23 456 789");
int i = 0;
while (words[i] != NULL) {
printf("%s\n", words[i]);
free(words[i]); // We're done with that word
i++;
}
free(words); // We're done with the list
return 0;
}
my code is ok when the string is sentence.
however, in this case, I want to print nothing(just like a space) when the string is number.
but what I go is
1
23
456
789
I expect to get
nothing shows here! just a space
For starters: You pass a non 0-terminated C-"string" (Copyword) to findWord() and in there call strlen() on it. This just doesn't crash your app by bad luck.

how to find duplicate string in an array of strings

I have an array of string from which i have to find duplicate string and then remove that duplicate string like i have string
char aa[50]="Amit Hanish Mahesh Amit"
Now Amit is duplicate and have to remove it from string .
#include "string.h"
main()
{
char x[100] = "Amit Hanish Mahesh Amit";
char y[3][100];
int i = 0, k = 0, j = 0, c = 0, end, t;
int current = 1;
while (x[i] != '\0') {
if (x[i] != ' ') {
y[k][j] = x[i];
j++;
i++;
} else {
// c = c + 1;
i++;
k++;
j = 0;
}
y[k][j] = '\0';
}
for (end = 1; end <= 3; end++) {
for (t = 0; t < end; t++) {
if (strcmp(y[end], y[t]) == 0) break;
}
if (end == t) {
strcpy(y[current],y[t]);
current++;
}
}
y[current] = 0;
printf("%s",y);
}
I have written a smalll routine for it .Does not seems to be worked .Any one have any suggestion where i am going wrong?
The other answers you got work fine for a small number strings (your example code only has 4). But, if you're comparing a large number this will be quite slow since you're doing n^2 comparisons. I'd suggest first splitting the string into an array of strings, then sorting the array using qsort(). In a sorted array all duplicates are guaranteed to be adjacent. This reduces the time from n^2 to n log n -- the time required to sort.
I would split the string array using strtok (see the man page).
So I would have something like this
char x[100]="Amit Hanish Mahesh Amit";
/* Preparing the result string */
size_t sz_result = sizeof(char) * (strlen(x) + 1);
char* result = (char*) malloc( sz_result );
result[0] = '\0';
/* Parsing the string from one element to the other */
char* elm = strtok(x, " ");
while( (elm = strtok(NULL, " ")) != NULL )
{
...
You will have each element of the string to verify if they are unique.
Then I would use something like a hashmap (you can use the one from the glib) or I would put the read string element in a new string only if it is not already in.
Here is an example for the second solution:
...
/* Is the element already in the result string? */
if ( strstr(result, elm) == NULL )
{
/* Then we should add it */
snprintf( result, sz_result - 1, "%s %s", result, elm );
}
}
In the end if you want x to be modified, you simply copy result in x:
strncpy( x, result, 99 );
Here is a sample code (not optimised, not using the strn* primitives, etc.)
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char x[100]="Amit Hanish Mahesh Amit";
/* Preparing the result string */
size_t sz_result = sizeof(char) * (strlen(x) + 1);
char* result = (char*) malloc( sz_result );
result[0] = '\0';
/* Parsing the string from one element to the other */
char* elm = strtok(x, " ");
if (elm != NULL) strcpy(result, elm);
while( (elm = strtok(NULL, " ")) != NULL )
{
/* Is the element already in the result string? */
if ( strstr(result, elm) == NULL )
{
/* Then we should add it */
strcat( result, " " );
strcat( result, elm );
}
}
strcpy( x, result );
fprintf( stdout, "Result: %s\n", x );
}
To remove duplicates from an array without preserving the order of elements:
sort the array
copy unique elements to the beginning of the array
remove the tail with duplicate elements
int remove_duplicates(StringArray array) {
if (! (array and array->items)) return 0; // empty array or NULL
StringArray_sort(array); // sort
// unique_copy()
String result = array->items, last = array->items + array->size;
for (String first = array->items; first != last; ++result) {
String_copy(result, first); // copy first to result
for (String prev = first; ++first != last and String_cmp(prev, first) == 0;)
{ /* skip adjacent equal items */ }
}
// shrink
return StringArray_remove(array, result, last);
}
Example
int main() {
char text[] = "Mahesh Amit Hanish Amit";
StringArray array = split(text, sizeof(text));
StringArray_dump(array, "<"); // print array before removing duplicates
if (remove_duplicates(array) < 0)
perror("error remove_duplicates(), OS error if any");
StringArray_dump(array, ">"); // print it after
StringArray_destroy(array);
return 0;
}
Where split() is:
StringArray split(const char* text, size_t size) {
if (! (text and text[size-1] == '\0')) return NULL;
StringArray array = StringArray_create();
if (! array) return NULL;
size_t n = -1;
for (const char* p = text; p != text+size; p += n+1) {
n = strcspn(p, " \t\n"); // find index of the next whitespace
if (n == 0) continue; // skip consecutive whitespace
// append characters in range [p, p+n)
// as a string to the array
const String string = String_create(p, n);
if (StringArray_append(array, string) < 0) {
String_destroy(string);
StringArray_destroy(array);
return NULL;
}
String_destroy(string);
}
return array;
}
Output
Mahesh<Amit<Hanish<Amit<
Amit>Hanish>Mahesh>
Full source code
I'm pretty sure, that the following line is not intended (assignment, not comparison)
if (end = t) {
See what happens, if you code a == and come back, if you still have problems.
Hint: Always code blanks around operators, so expressions are easier to read.
It's always fun to try to solve this kind of simple problems in C as exercise. Here's my take.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* strstrn(const char *haystack, const char *needle, size_t needle_len)
{
while((haystack = strchr(haystack, *needle)))
{
if (strncmp(haystack, needle, needle_len) == 0)
return (char *) haystack;
haystack++;
}
return NULL;
}
char* find_duplicate(const char* str, size_t len, size_t dup_len)
{
for(size_t i = 0; i < (len - dup_len); i++)
{
char* r = strstrn(str + i + 1, str + i, dup_len);
if(r) return r;
}
return NULL;
}
int main(int argc, char** argv)
{
if(argc < 3)
{
fprintf(stderr, "Usage: %s haystack dup_size\n", argv[0]);
return 1;
}
char* haystack = argv[1];
size_t len = atoi(argv[2]);
char* r;
while((r = find_duplicate(haystack, strlen(haystack), len)))
{
strcpy(r, r + len);
}
puts(haystack);
return 0;
}
/*
* C Program to Find the Frequency of Every Word in a
* given String
*/
#include <stdio.h>
#include <string.h>
void main()
{
int count = 0, c = 0, i, j = 0, k, space = 0;
char str[100], p[50][100], str1[20], ptr1[50][100];
printf("Enter the string\n");
scanf(" %[^\n]s", str);
printf("string length is %d\n", strlen(str));
for (i = 0;i<strlen(str);i++)
{
if ((str[i] == ' ')||(str[i] == ', ')||(str[i] == '.'))
{
space++;
}
}
for (i = 0, j = 0, k = 0;j < strlen(str);j++)
{
if ((str[j] == ' ')||(str[j] == 44)||(str[j] == 46))
{
p[i][k] = '\0';
i++;
k = 0;
}
else
p[i][k++] = str[j];
}
k = 0;
for (i = 0;i <= space;i++)
{
for (j = 0;j <= space;j++)
{
if (i == j)
{
strcpy(ptr1[k], p[i]);
k++;
count++;
break;
}
else
{
if (strcmp(ptr1[j], p[i]) != 0)
continue;
else
break;
}
}
}
for (i = 0;i < count;i++)
{
for (j = 0;j <= space;j++)
{
if (strcmp(ptr1[i], p[j]) == 0)
c++;
}
printf("%s -> %d times\n", ptr1[i], c);
c = 0;
}
}

Resources