C - function that compresses characters - c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char * compress(char *input, int size){
char *inputa;
char compressedString[100];
inputa = (char*)malloc(sizeof(size));
snprintf (inputa, size, "%s", input);
int i = 0;
int x;
int counter;
while(i < size){
counter = 1;
x = i;
while (inputa[x] == inputa[x + 1] && (x+1) < size){
x++;
counter++;
}
if (i != x){
i = x;
}else{
i++;
}
}
return inputa;
}
main(){
char ez[] = "blaablaaa";
printf("%s \n", compress(ez, sizeof(ez)));
printf("%s", ez);
return 0;
}
So, I am trying to make this function that compresses consecutive characters (eg. "blaablaaa" to "bla2bla3"). My thought process is to put the inputa[x] on the compressed array and next to it the counter, but I can't seem to make it to work.

Lets take a look at these two lines:
inputa = (char*)malloc(sizeof(size));
snprintf (inputa, size, "%s", input);
size has type int, so sizeof(size) is the size of an integer, which is probably 4.
You used malloc to allocate 4 bytes.
Then you use snprintf to try to copy all of your input (blaablaaa, 10-bytes long) into a buffer that is only 4 bytes long.
10 bytes won't fit into a 4 byte buffer.
I'm not sure what you're trying to do there, but it is not correct.

1) Your allocated buffer was too short:
inputa = (char*)malloc(sizeof(size));
It allocates only 4 bytes.
You needed
inputa = (char*)malloc(sizeof(char)*size + 1 ));
2) You forgot to release the allocated memory.
3) The algorithm itself needed the improvements. Comments in the code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
/* reverse: reverse string s in place */
void reverse(char s[])
{
int i, j;
char c;
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
/* itoa is not a standard function */
/* itoa: convert n to characters in s */
void itoa1(int n, char s[])
{
int i, sign;
if ((sign = n) < 0) /* record sign */
n = -n; /* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
char * compress(char *input, int size){
int i = 0;
int r; // number of repetitions
char add[2]; // current character buffer
char rep[32]; // repetitions buffer
char c; // current character
char *compr = (char* )malloc(sizeof(char)*size + 1); // memory for the compressed string
compr[0] = 0; // terminate the buffer
add[1] = 0; // terminate the buffer
while(i < size){
c = add[0] = input[i]; // get a character
strcat(compr,add); // add to compr
r = 1; // default number of repetitions is one
while(1) // count and add to the string
{
if(c == input[i+1] )
{ // find how many characters follows c
r++; // number of repetition
i++; // moving along the input buffer
}
else
{
// check the r for number of repetitions
if( r > 1)
{
// there were repetitions:
// char * itoa ( int value, char * str, int base );
itoa1(r,rep); // get the number
strcat(compr,rep); // add repetition number to the compressed string
}
i++;// advance to the next character
break;
} // else
}// while
} //while
return compr;
}
int main(void){
char sg7[] = "BLaaaBBLLaaaaXXXaaY";
char ez[] = "blaablaaa";
char *ptr;
printf("%s \n", ptr = compress(sg7, strlen(sg7) ) );
printf("%s \n", sg7);
free(ptr);
printf("\n");
printf("%s \n", ptr = compress(ez, strlen(ez)));
printf("%s \n", ez);
free(ptr);
return 0;
}
Output:
BLa3B2L2a4X3a2Y
BLaaaBBLLaaaaXXXaaY
bla2bla3
blaablaaa
I hope it helps.

Related

How to modify a char pointer passed as parameter in a function?

So, I am doing my own rudimentary version of itoa(), and I just realized I don't exactly know how to modify a char* passed as parameter, or if there is something wrong with the way I am doing it...
The way I am doing it is by doing malloc() onto the buffer passed as argument, then write the number into it. This is apparently working before returning from the function (the buffer is printed correctly), but then when trying to print it back in main(), it segfaults.
If I understand the error correctly, I am changing the address buff points to inside with that malloc(), and then modify its contents, but the new malloc'd address inside is not returned. How could I do that without changing the parameters or the return value?
int itoa(int i, char *buff) {
int length = 0;
// get the length
long temp = 1;
while (temp <= i) {
length++;
temp *= 10;
}
buff = malloc(length + 1); // buff will have 'length' chars + one extra (\0)
int j = 0;
do { /* generate digits in reverse order */
buff[j++] = i % 10 + '0'; /* get next digit */
} while ((i /= 10) > 0); /* delete it */
buff[length] = '\0';
// reverse it
int k, l;
char c;
for (k = 0, l = length - 1; k<l; k++, l--) {
c = buff[k];
buff[k] = buff[l];
buff[l] = c;
}
printf("buff's now:%s\n", buff);
return 0;
}
int main() {
char *buff = NULL;
itoa(45, buff);
printf("%s\n", buff);
}
Your pointer isn't modified as it was copied. You can read more here. You can try this code after reading the above link.
#include <stdlib.h>
#include <stdio.h>
int itoa_(int i, char **parabuff)
{
int length = 0;
// get the length
long temp = 1;
while (temp <= i)
{
length++;
temp *= 10;
}
char *buff = malloc(length + 1); // buff will have 'length' chars + one extra (\0)
int j = 0;
do
{ /* generate digits in reverse order */
buff[j++] = i % 10 + '0'; /* get next digit */
} while ((i /= 10) > 0); /* delete it */
buff[length] = '\0';
// reverse it
int k, l;
char c;
for (k = 0, l = length - 1; k < l; k++, l--)
{
c = buff[k];
buff[k] = buff[l];
buff[l] = c;
}
printf("buff's now: %s\n", buff);
*parabuff = buff;
return 0;
}
int main()
{
char *buff = NULL;
itoa_(45, &buff);
printf("buff in main: %s\n", buff);
}
//OUTPUT
buff's now: 45
buff in main: 45

Why is variable being mutated in C program?

While working through exercise 3-5 in The C Programming Language, I've come across the following unexpected behavior.
#include <stdio.h>
#include <string.h>
// inspired by: http://www.eng.uerj.br/~fariasol/disciplinas/LABPROG/C_language/Kernighan_and_Ritchie/solved-exercises/solved-exercises.html/krx305.html
void reverse(char s[]) {
int c, i, j;
for ( i = 0, j = strlen(s)-1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
void itob(int n, char s[], int b) {
static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i = 0,
sign;
if ( b < 2 || b > 36 ) {
fprintf(stderr, "EX3_5: Cannot support base %d\n", b);
}
if ((sign = n) < 0) {
n = -n;
}
do {
s[i++] = digits[n % b];
} while (n /= b);
if (sign < 0) {
s[i++] = '-';
}
s[i] = '\0';
reverse(s);
}
int main() {
int base = 2,
input;
char buffer[5] = "0000";
input = 127;
itob(input, buffer, base);
printf("%d in base %d is %s\n", input, base, buffer);
// 127 in base 2 is 1111111
input = 128;
itob(input, buffer, base);
printf("%d in base %d is %s\n", input, base, buffer);
// 0 in base 2 is 10000000
// Why is input now 0?!
return 0;
}
Why is the value of the input variable being changed (only when input is greater than 127)? I'm new to C but this seems very unexpected. As far as I understand, function arguments are pass-by-value.
Your buffer isn't big enough. You allocated space for 4 chars and a null terminator:
char buffer[5] = "0000";
but you're trying to stuff 8 chars and a null terminator in there with itob(input, buffer, base);. That leads to a buffer overflow and undefined behavior.
Try to use larger buffersize, with only 4 chars you can't convert number larger than 127.

How to output my results all the way at the end of my program versus at the end of each iteration? (Updated version of previous query)

So my program takes a string, and then outputs it as a marquee sign. I have a for loop so that it may take multiple strings and then outputs each of the strings as a sign.
My problem is: after each iteration, it outputs the sign, and then continues to prompt me for the next string when I want it to just take in all my inputs at once, and then output every sign at the very end. Here is what I'm talking about:
Current Input:
3
Hello World!
5
Sign #1: (This is the output)
[Hello]
[ello ]
[llo W]
[lo Wo]
[o Wor]
[ Worl]
[World]
[orld!]
[rld! ]
[ld! H]
[d! He]
[! Hel]
[ Hell]
Activist
10
Sign #2: (This is the output)
[Activist ]
LOL
2
Sign #3: (This is the output)
[LO]
[OL]
[L ]
[ L]
This is what I want it to do:
Input:
3
Hello World!
5
Activist
10
LOL
2
Output:
Sign #1:
[Hello]
[ello ]
[llo W]
[lo Wo]
[o Wor]
[ Worl]
[World]
[orld!]
[rld! ]
[ld! H]
[d! He]
[! Hel]
[ Hell]
Sign #2:
[Activist ]
Sign #3:
[LO]
[OL]
[L ]
[ L]
Here is my ORIGINAL code:
#include <stdio.h>
#include <string.h>
void ignoreRestOfLine(FILE *fp) {
int c;
while ((c = fgetc(fp)) != EOF && c != '\n');
}
int main() {
int num_times, count = 0;
int marq_length, sign = 0;
scanf("%d ", &num_times);
char s[100];
for (count = 0; count < num_times; count++) {
if (fgets(s, sizeof(s), stdin) == NULL) {
// Deal with error.
}
if (scanf("%d", &marq_length) != 1) {
// Deal with error.
}
ignoreRestOfLine(stdin);
size_t n = strlen(s) - 1;
int i, j;
if (s[strlen(s)-1] == '\n')
s[strlen(s)-1] = '\0';
printf("Sign #%d:\n", ++sign);
if (n <= marq_length) {
printf("[%-*s]\n", marq_length, s);
} else {
for (i = 0; i < n + 1; i++) {
putchar('[');
for (j = 0; j < marq_length; j++) {
char c = s[(i + j) % (n + 1)];
if (!c)
c = ' ';
putchar(c);
}
printf("]\n");
}
}
}
return 0;
}
Here is my UPDATED code, where I added the part of my code that actually outputs the string in a marquee sign into a function. I just don't know how to properly call it back to the main function so it can output all the signs at the very end:
#include <stdio.h>
#include <string.h>
void ignoreRestOfLine(FILE* fp){
int c;
while ( (c = fgetc(fp)) != EOF && c != '\n');
}
char getSign(char s[100], int marq_length);
char getSign(char s[100], int marq_length){
int count =0;
int sign =0;
//char s[100];
if ( fgets(s, sizeof(s), stdin) == NULL )
{
// Deal with error.
}
if ( scanf("%d", &marq_length) != 1 )
{
// Deal with error.
}
ignoreRestOfLine(stdin);
size_t n = strlen(s)-1;
int i,j;
if(s[strlen(s)-1] == '\n')
s[strlen(s)-1] = '\0';
printf("Sign #%d:\n", ++sign);
if (n <= marq_length) {
printf("[%-*s]\n", marq_length, s);
} else {
for (i = 0; i < n + 1; i++) {
putchar('[');
for (j = 0; j < marq_length; j++) {
char c = s[(i + j) % (n + 1)];
if (!c)
c = ' ';
putchar(c);
}
printf("]\n");
}
}
}
int main(){
int i, num_times, sign_length;
char string[100];
scanf("%d", &num_times);
//char *results=malloc(num_times * sizeof(char));
for(i=0 ;i<num_times;i++){
scanf("%s", string);
scanf("%d", &sign_length);
printf((getSign(string, sign_length)));
}
return 0;
}
I think it is good to read all input and then print results because input is short and these size are easy to predict.
Your main() function should be like this
int main(void){
int i, num_times, *sign_length;
char (*string)[100];
/* read number of test cases */
scanf("%d", &num_times);
/* allocate buffer to store input */
sign_length = malloc(sizeof(*sign_length) * num_times);
string = malloc(sizeof(*string) * num_times);
if (sign_length == NULL || string == NULL) {
free(sign_length);
free(string);
return 1;
}
/* read input */
for(i=0 ;i<num_times;i++){
scanf("%99s", string[i]);
scanf("%d", &sign_length[i]);
}
/* process and print */
for(i=0 ;i<num_times;i++){
getSign(string[i], sign_length[i]);
}
/* cleanup */
free(string);
free(sign_length);
return 0;
}
and the part that are trying to destroy the input in getSign()
if ( fgets(s, sizeof(s), stdin) == NULL )
{
// Deal with error.
}
if ( scanf("%d", &marq_length) != 1 )
{
// Deal with error.
}
ignoreRestOfLine(stdin);
have to be deleted.
#include <stdlib.h> have to be added to the head of your code to use malloc() and free().
UPDATE: Here is a program with problems fixed.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void getSign(char s[100], int marq_length, int case_number);
void getSign(char s[100], int marq_length, int case_number){
size_t n = strlen(s)-1;
size_t i,j;
if (strlen(s) < n) n = 0;
if(s[n] == '\n')
s[n] = '\0';
else
n++;
printf("Sign #%d:\n", case_number);
if (n <= (size_t)marq_length) {
printf("[%-*s]\n", marq_length, s);
} else {
for (i = 0; i < n + 1; i++) {
putchar('[');
for (j = 0; j < (size_t)marq_length; j++) {
char c = s[(i + j) % (n + 1)];
if (!c)
c = ' ';
putchar(c);
}
printf("]\n");
}
}
}
int main(void){
int i, num_times, *sign_length;
char (*string)[100];
/* read number of test cases */
if(scanf("%d", &num_times) != 1) return 1;
/* allocate buffer to store input */
sign_length = malloc(sizeof(*sign_length) * num_times);
string = malloc(sizeof(*string) * num_times);
if (sign_length == NULL || string == NULL) {
free(sign_length);
free(string);
return 1;
}
/* read input */
for(i=0 ;i<num_times;i++){
int dummy;
while((dummy = getchar()) != '\n' && dummy != EOF); /* skip rest of previous line */
if(scanf("%99[^\n]%d", string[i], &sign_length[i]) != 2) {
free(sign_length);
free(string);
return 1;
}
}
/* process and print */
for(i=0 ;i<num_times;i++){
getSign(string[i], sign_length[i], i + 1);
}
/* cleanup */
free(string);
free(sign_length);
return 0;
}
The approach I'd take here is to either store the input until all input is read and only then to generate the output, or to store the output and defer it's printing until the end.
The first is IMHO opinion the better approach, because the amount of data to store is less. OTOH is storing the output a good first step to parallelize taking input and generating output. I go with the later as this is closer to the wording in your question.
OK, your output is basically a C string. So you need to store one of these for each input that you get. Luckily you know even before the first iteration how many inputs you'll get, so you can just allocate the correct amount of space beforehand:
char const ** outputs; // A pointer to (an array of) constant C strings
outputs = malloc(sizeof(*outputs) * numInputs);
Then, you read input as you do it and generate your output into a C string. You've been using a stack allocated (constant size) buffer for that. To be able to reuse that buffer in each iteration you need to copy your result out of it:
char * result = malloc(strlen(sign) + 1);
strcpy(result, sign);
And the store that into your array of outputs:
outputs[currentIteration] = result;
Finally, at the end you print each output and free the allocated memory when done with it:
for (size_t o = 0; o < numOutputs; ++o) {
printf("%s\n", outputs[o]);
free(outputs[o]);
}
At the end, don't forget to also free the array that has been allocated for the outputs:
free(outputs);
Notes: You should check each and every allocation whether it succeeded. Moreover, using a constant sized buffer (on the stack) is OK only if you make absolutely sure that this buffer will never overflow! You should try to pack as much of the above and your sign generation in (small) functions.
Sketch of the overall code:
int main() {
// read how many inputs you'll get
// allocate outputs
// iterate, so that for each input:
// you read the input
// generate the sign
// copy the result into the outputs array
// iterate over all outputs
// print output
// free allocated memory of that output
// free memory for outputs
}
Reading the input and generating the sign should be done in two distinct functions (so its neither the original nor the updated code). Basically I think having these functions should give you a reasonable code structure:
// Read both the string and length, allocating memory for the string
bool read_input(char **string, unsigned * marq_length);
// Could alternatively be done with a fixed buffer
bool read_input(char * string, size_t max_string_size, unsigned * marq_length);
// Note: for bool include stdbool, or use a char instead
And one to generate the sign:
// Store the result in the fixed size buffer at dest, check for overflow!
void generate_sign(char * dest, size_t max_dest_size, char const * input, unsigned marq_length);
Things like printing the outputs could be done directly in main, or in a dedicated function.

Replace spaces with tab character

I just finished the first chapter of The C Programming Language and there are a few exercises before moving on. I already completed the one to replace the tab character with spaces which was fairly easy, but I am stuck on the one to replace space characters with the proper amount of tabs and spaces to achieve the same spacing.
My implementation "sometimes" works, so essentially it doesn't work. Here is the function:
#define TABLEN 5
// entab: replace consecutive spaces of length TABLEN with the tab character
void entab(char string[])
{
int i, consec;
int to, from, tabloc;
consec = 0;
for (i = 0; string[i] != '\0'; ++i) {
// count consecutive spaces in a string
if (string[i] == ' ') ++consec;
else consec = 0;
if (consec >= TABLEN) {
// set location to insert tab character
tabloc = (i - TABLEN) + 1;
for (to = tabloc, from = i;
string[from] != '\0'; ++from, ++to)
{
// replace space characters
string[to] = string[from];
}
string[tabloc] = '\t';
string[to] = '\0';
i = tabloc;
consec = 0;
}
}
}
This function is extremely inconsistent in working successfully to the point where there isn't even a pattern of when it does and doesn't work. By "doesn't work", I mean one of two situations. 1.) the spaces are deleted and no tab character is inserted, or 2.) the spaces are deleted, a tab character is inserted, but somehow an extra space is added in. These issues have led me to realize that the problem exists in the loop that replaces the spaces, but I'm so new to C that I have no idea what is wrong. Can someone point me in the right direction here?
Here's how tabs work:
If you typed
Tab
v v v v
------------------------
| a
|a a
|aa a
|aaa a
|aaaa a
Notice how if there was 5, 4, 3, 2, or 1 spaces, they all could be equally represented as a tab. This is why 5 spaces doesn't equal a tab (even when the tab size is set to 5). Consider this case as well:
v v v v
------------------------
|aaaa a
| 12345
But when you replace those 5 spaces with a tab, you get:
v v v v
------------------------
|aaaa a
| 12345
Here's an working example:
#include <stdio.h>
#include <string.h>
void Print_As_String(char * buffer, unsigned int size);
void Print_As_Hex(char * buffer, unsigned int size);
void Convert_Tab_To_Space(char * buffer, unsigned int size, unsigned int tab_size);
int main(unsigned int argc, char * argv[]){
unsigned int i = 0;
unsigned int arg_length = 0;
if (argc <= 1){
printf("Usage: \"Text with spaces\", \"More text with spaces\", etc\n");
return -1;
}
for (i = 1; i < argc; i++){
arg_length = strlen(argv[i]);
Print_As_String (argv[i], arg_length);
Print_As_Hex (argv[i], arg_length);
Convert_Tab_To_Space(argv[i], arg_length, 8);
Print_As_String (argv[i], arg_length);
Print_As_Hex (argv[i], arg_length);
}
return 0;
}
void Print_As_String(char * buffer, unsigned int size){
printf("%.*s\n", size, buffer);
}
void Print_As_Hex(char * buffer, unsigned int size){
unsigned int i = 0;
const char hex_table[16] = "0123456789ABCDEF";
for (i = 0; i < size; i++){
unsigned char high_byte = 0;
unsigned char low_byte = 0;
high_byte = (buffer[i] & 0xF0) >> 4;
low_byte = (buffer[i] & 0x0F) >> 0;
putc(hex_table[high_byte], stdout);
putc(hex_table[low_byte], stdout);
putc(' ', stdout);
}
putc('\n', stdout);
}
void Shift_Characters_Left(char * buffer,
unsigned int position_start,
unsigned int position_end,
unsigned int size);
void Convert_Tab_To_Space(char * buffer, unsigned int size, unsigned int tab_size){
unsigned int i = 0;
unsigned int x = 0; /* x is used
for getting the position in
the current line. This is
different from 'i' because
there may be many lines in
one string.
*/
for (i = 0; i < size; i++){
if (buffer[i] == '\t'){ /* the x coordinates
change in this fashion when a new
tab is found.
*/
x += tab_size - (x % tab_size);
} else if (buffer[i] == ' '){
unsigned int tab_remainder = 0; // how many spots are left for a tab
unsigned int space_i = 1; // space index
tab_remainder = (x % tab_size);
while ((i + space_i) < size){
/* if the space count makes up for the
missing spots in the tab remainder,
replaces the spaces with a tab
*/
if ((tab_remainder + space_i) == tab_size){
Shift_Characters_Left(buffer, // move the spot at the end of
i + space_i, // the spaces to the spot at
i + 1, // the start of the spaces
size);
buffer[i] = '\t';
}
if (buffer[i + space_i] != ' '){
i += space_i;
break;
}
space_i++;
}
} else if (buffer[i] == '\n'){
x = 0;
} else {
x++;
}
}
}
void Shift_Characters_Left(char * buffer,
unsigned int position_start,
unsigned int position_end,
unsigned int size){
memmove(buffer + position_end,
buffer + position_start,
size - position_end);
memset(&buffer[position_start], 0, (size - 1) - position_start);
}
But there is an unaddressable error I get when I test this problem. I think it's something i'm doing wrong with memset (probably an off-by-one error).
The following works fine. Check the differences in the indexes
#include <stdio.h>
#define TABLEN 5
// entab: replace consecutive spaces of length TABLEN with the tab character
void entab(char string[])
{
int i, consec;
int to, from, tabloc;
printf("%s\n",string);
consec = 0;
for (i = 0; string[i] != '\0'; ++i) {
// count consecutive spaces in a string
if (string[i] == ' ') ++consec;
else consec = 0;
if (consec >= TABLEN) {
// set location to insert tab character
tabloc = (i - TABLEN) + 1;
for (to = tabloc+1, from = i+1;
string[from] != '\0'; ++from, ++to)
{
// replace space characters
string[to] = string[from];
}
string[tabloc] = '\t';
string[to] = '\0';
i = tabloc+1;
consec = 0;
}
}
printf("%s",string);
}
int main(void) {
// your code goes here
char a[] = "hello wor l d";
entab(a);
return 0;
}

all possible combinations in a string in C

I am trying to print all possible combinations of the string 'abc' using C. Can someone help point out where in this code I am going wrong ? I am using the algorithm mentioned here:
http://hackercs.com/videos/Combinations-of-a-String-Part-2/
Thanks for your time and help. ( BTW, the goal is to use recursion here)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void combination(char **curString,int allowedStart,char **outBuffer,int length)
{
//check for allowed chars.
// if not return.
// else
// for each char in the allowed char
// copy into buffer
//print buffer
//combine buffer and over next allowed chars
//remove from buffer.
if (allowedStart == length)
return;
else
{
int curr;
for (curr = allowedStart;curr<length; curr++){
//need to copy 'a' into outbuffer and keep appending to outbuffer.
printf("allowedStart = %d\n",allowedStart);
printf("curr = %d\n",curr);
(*outBuffer)[curr] = (*curString)[allowedStart];
printf("outbuff is %s\n",*outBuffer);
combination(curString,curr+1,outBuffer,length);
printf("return\n");
(*outBuffer)[length-1] = '\0';
} //else
} //for
}
main()
{
char *var = "abc";
int length = strlen(var);
printf("length = %d\n",length);
char *outBuffer = malloc ( length * sizeof (char));
bzero(outBuffer,3);
combination(&var,0,&outBuffer,length);
}
For starters, you're going wrong here:
char *var = "abc";
int length = strlen(var);
printf("length = %d\n",length);
char *outBuffer = malloc ( length * sizeof (char));
bzero(outBuffer,3);
This is very confused code. It's mixing dynamic buffer length handling (the strlen() call) with static ones (the 3 in the bzero() call). It's also Doing It Wrong, by using sizeof (char) (which is guaranteed to be 1 by the C language, and thus just adds noise and confusion). Also, the number of characters needed to hold a 3-character printable string in C is not 3, but 4 since you need one character for the terminating '\0'.
Got this working.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void combination(char **curString,int allowedStart,char **outBuffer,int length)
{
//check for allowed chars.
// if not return.
// else
// for each char in the allowed char
// copy into buffer
//print buffer
//combine buffer and over next allowed chars
//remove from buffer.
int curr;
if ( allowedStart == length )
return;
else {
for (curr = allowedStart;curr<length; curr++){
//need to copy 'a' into outbuffer and keep appending to outbuffer.
// printf("allowedStart= %d curr= %d \n",allowedStart,curr);
(*outBuffer)[curr] = (*curString)[allowedStart];
//adjust for appending.
int i = 0;
while (i < length)
{
if ( ((*outBuffer)[i] == '\0') && ((*outBuffer)[i+1] != '\0') )
{
// printf("in here\n");
(*outBuffer)[i] = (*outBuffer)[i+1];
(*outBuffer)[i+1] = '\0';
}
i++;
}
// printf("added curr%d %c \n",curr, (*outBuffer)[curr]);
printf("***************************************COMBO: %s\n",*outBuffer);
allowedStart = curr+1;
// printf("allowedStart%d %c \n",allowedStart,(*curString)[allowedStart]);
combination(curString,allowedStart,outBuffer,length);
// printf("removing%d %c\n",curr,(*outBuffer)[curr]);
(*outBuffer)[curr] = ' ';
// printf("**************RETURNCOMBO: %s\n",*outBuffer);
} //else
} //for
}
main()
{
char *var = "abcd";
int length = strlen(var);
printf("length = %d\n",length);
// printf("Intial word is %s\n",var);
char *outBuffer = malloc ( (length+1) * sizeof (char));
bzero(outBuffer,length);
combination(&var,0,&outBuffer,length);
}
#include <iostream>
#define PRINTLN(STR) std::cout << STR << std::endl
#define SWAP(ARRAY, I, J) if(I != J) { ARRAY[I] ^= ARRAY[J]; ARRAY[J] ^= ARRAY[I]; ARRAY[I] ^= ARRAY[J]; }
void PrintCombinations_Rec(char* str, size_t idx)
{
const size_t len = strlen(str);
if( len == idx)
PRINTLN(str);
else
{
for (size_t i = idx; i < len; ++i)
{
SWAP(str, idx, i);
PrintCombinations_Rec(str, idx + 1);
SWAP(str, i, idx);
}
}
}
void PrintCombinations(const char* input)
{
const size_t len = strlen(input);
char* str = new char[len + 1];
strncpy_s(str, len + 1, input, len);
// Recursive call
PrintCombinations_Rec(str, 0);
delete[] str;
}
int main(int argc, char** argv)
{
PrintCombinations("ABCD");
return EXIT_SUCCESS;
}

Resources