I am a complete noob to c. I have downloaded a code from internet. It generates all possible combination of characters. I want to transfer this output to a text file. I have tried few things but unable to do it. Can anybody suggest me the necessary changes? Here is the code.a
EDIT: I have changed the put command to fputs. i tried all possible combinations.fputs(&str[1],f), fputs("&str[1]" ,"f"), fputs("&str[1]",f) and fputs(&str,"f"). but nothing worked. what to do next?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MINCHAR 33
#define MAXCHAR 126
char *bruteforce(int passlen, int *ntries);
int main(void) {
int i, wdlen, counter;
char *str;
clock_t start, end;
double elapsed;
FILE *myfile;
myfile = fopen("ranjit.txt","w");
do {
printf("Word length... ");
scanf("%d", &wdlen);
} while(wdlen<2);
start = clock();
bruteforce(wdlen, &counter);
end = clock();
elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
fprintf(myfile,"\nNum of tries... %d \n",counter);
fprintf(myfile,"\nTime elapsed... %f seconds\n",elapsed);
return counter;
}
char *bruteforce(int passlen, int *ntries) {
int i;
char *str;
FILE *f;
f = fopen("sandip.txt","w");
*ntries=0;
passlen++;
str = (char*)malloc( passlen*sizeof(char) );
for(i=0; i<passlen; i++) {
str[i]=MINCHAR;
}
str[passlen]='\0';
while(str[0]<MINCHAR+1) {
for(i=MINCHAR; i<=MAXCHAR; i++) {
str[passlen-1]=i;
(*ntries)++;
fputs("&str[1]",f);
}
if(str[passlen-1]>=MAXCHAR) {
str[passlen-1]=MINCHAR;
str[passlen-1-1]++;
}
for(i=passlen-1-1; i>=0; i--) {
if(str[i]>MAXCHAR) {
str[i]=MINCHAR;
str[i-1]++;
}
}
}
return NULL;
}
Replace puts with fputs, which takes a FILE* as its second argument. You will need to pass that in to bruteforce.
For what it's worth, you can use shell redirection to create a file with the output...
./myprogram > output.txt
Related
I need to feel a file with a list of purchase
I declared a type struct name purchase that must contain the information : item, price and date of purchase in day/month/year ordered by date of purchase.
But it doesn't work and I don't know why.
This is the code source:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct Date {
int day,month,year;
} Date;
typedef struct purchase{
char item[20];
float price;
Date date_purchase;
} purchase;
void fillFile(char Name_F[30] , purchase T[30] , int N) {
FILE * P_Fichier;
P_Fichier=fopen(Name_F,"w");
int i=1;
while (i< N )
{
fprintf(P_Fichier,T[i].item);
fprintf(P_Fichier,T[i].price);
fprintf(P_Fichier,T[i].date_purchase);
i++;
}
}
You need to specify the format specifier in fprintf(), like this:
fprintf(P_Fichier, "%s\n", T[i].item);
fprintf(P_Fichier, "%f\n", T[i].price);
fprintf(P_Fichier, "%d/%d/%d\n", T[i].date_purchase.day, T[i].date_purchase.month, T[i].date_purchase.year);
These are the typical format specifiers that'd use with printf() too, so %s for string, %f for float and %d for int.
I'd suggest you to check if the file is opened before attempting to write into it (file pointer is going to be NULL if it didn't open). You also need to close the file when you are done writing your data, like fclose(P_Fichier);.
Moreover, i should start from 0, otherwise you'll skip your first element. However, since you already know how many times you want the loop to be executed, I'd advise you to use a for-loop, like this:
for (int i = 0; i < N; ++i)
Putting everything together, you should get:
void fillFile(char Name_F[30], purchase T[30], int N) {
FILE* P_Fichier;
P_Fichier = fopen(Name_F, "w");
if (P_Fichier == NULL) {
# file failed to open
fprintf(stderr, "Unable to open %s file.\n", Name_F);
return;
}
for (int i = 0; i < N; ++i) {
fprintf(P_Fichier, "%s\n", T[i].item);
fprintf(P_Fichier, "%f\n", T[i].price);
fprintf(P_Fichier, "%d/%d/%d\n", T[i].date_purchase.day, T[i].date_purchase.month, T[i].date_purchase.year);
}
fclose(P_Fichier);
}
You have to use format specifiers to use fprintf().
Also results of fopen() should be checked and files opened should be closed.
void fillFile(char Name_F[30] , purchase T[30] , int N) {
FILE * P_Fichier;
P_Fichier=fopen(Name_F,"w");
if (P_Fichier == NULL) return; /* check if file open is successful */
int i=1;
while (i< N )
{
fprintf(P_Fichier,"%s\n",T[i].item); /* %s for strings */
fprintf(P_Fichier,"%f\n",T[i].price); /* %f for float */
fprintf(P_Fichier,"day:%d, month:%d, year:%d\n", /* %d for int */
T[i].date_purchase.day, T[i].date_purchase.month, T[i].date_purchase.year);
i++;
}
fclose(P_Fichier); /* close file when done */
}
I got my code working to an extent, but I need some more help. If I needed to remove the word "an", from sentence: "I ate an apple whilst looking at an ape.", it only removes the first "an" and not the second, how do I repeat the loop so it deletes all "an"s? I need the final sentence, after the code has been ran, to be: "I ate apple whilst looking at ape.". That is the goal im trying to achieve
Sorry for not including the code.
Here it is:
#include "RemoveFromText.h"
#include <stdlib.h>
#include <string.h>
int findFirstSubstring(char textToChange[], char removeThis[])
{
int size = strlen(textToChange);
int subStringLength = strlen(removeThis);
for(int i=0; i<size; i++)
{
if(textToChange[i] == removeThis[0])
{
int j = 0;
while(textToChange[i+j] == removeThis[j])
{
j++;
if(j==subStringLength)
{
return i;
}
}
}
}
return -1;
}
void removeFromText( char textToChange[], char removeThis[])
{
int textLength = strlen(textToChange);
if(findFirstSubstring(textToChange, removeThis) >= 0)
{
int subStringIdx = findFirstSubstring(textToChange, removeThis);
int loopVariabele = 0;
for(loopVariabele = subStringIdx; loopVariabele<textLength; loopVariabele++)
{
textToChange[loopVariabele] = textToChange[loopVariabele + strlen(removeThis)];
}
}
}
Leveraging 'strstr', and 'memmove' standard "C" library functions
// Remove all occurences of 'source' from 'message'.
void removeAll(char *message, char *source)
{
int len = strlen(source) ;
for (char *x = message ; x=strstr(x, source) ; ) {
// Copy everything after 'source', including terminating nul.
memmove(x, x+len, strlen(x+len)+1) ;
} ;
}
Notes:
that solution that not properly address the trailing space(s) after a word. This can be addressed by chaning the 'memmove'.
Probably make sense to make the function return the number of substitutions, or some other meaningful result
I am trying to implement a simple audio delay in C.
i previously made a test delay program which operated on a printed sinewave and worked effectively.
I tried incorporating my delay as the process in the SFProcess - libsndfile- replacing the sinewave inputs with my audio 'data' input.
I nearly have it but instead of a clean sample delay I am getting all sorts of glitching and distortion.
Any ideas on how to correct this?
#include <stdio.h>
#include </usr/local/include/sndfile.h>//libsamplerate libsamplerate
//#include </usr/local/include/samplerate.h>
#define BUFFER_LEN 1024 //defines buffer length
#define MAX_CHANNELS 2 //defines max channels
static void process_data (double *data, double*circular,int count, int numchannels, int circular_pointer );
enum {DT_PROGNAME,ARG_INFILE,ARG_OUTFILE,ARG_NARGS, DT_VOL};
int main (int argc, const char * argv[])//Main
{
static double data [BUFFER_LEN]; // the buffer that carries the samples
double circular [44100] = {0}; // the circular buffer for the delay
for (int i = 0; i < 44100; i++) { circular[i] = 0; } // zero the circular buffer
int circular_pointer = 0; // where we currently are in the circular buffer
//float myvolume; // the volume entered by the user as optional 3rd argument
SNDFILE *infile, *outfile;
SF_INFO sfinfo;
int readcount;
const char *infilename = NULL;
const char *outfilename = NULL;
if(argc < ARG_NARGS) {
printf("usage: %s infile outfile\n",argv[DT_PROGNAME]);
return 1;
}
//if(argc > ARG_NARGS) {
//
// myvolume = argv[DT_VOL];
//};
infilename = argv[ARG_INFILE];
outfilename = argv[ARG_OUTFILE];
if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))
{printf ("Not able to open input file %s.\n", infilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
};
if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo)))
{ printf ("Not able to open output file %s.\n", outfilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
} ;
while ((readcount = sf_read_double (infile, data, BUFFER_LEN)))
{ process_data (data, circular, readcount, sfinfo.channels, circular_pointer) ;
sf_write_double (outfile, data, readcount) ;
};
sf_close (infile) ;
sf_close (outfile) ;
printf("the sample rate is %d\n", sfinfo.samplerate);
return 0;
}
static void process_data (double *data, double *circular, int count, int numchannels, int circular_pointer) {
//int j,k;
//float vol = 1;
int playhead;
int wraparound = 10000;
float delay = 1000; // delay time in samples
for (int ind = 0; ind < BUFFER_LEN; ind++){
circular_pointer = fmod(ind,wraparound); // wrap around pointer
circular[circular_pointer] = data[ind];
playhead = fmod(ind-delay, wraparound); // read the delayed signal
data[ind] = circular[playhead]; // output delayed signal
circular[ind] = data[ind]; // write the incoming signal
};
//volume
/*for (j=0; j<numchannels; j++) {
for (k=0; k<count; k++){
data[k] = data[k]*-vol;*/
//}printf ("the volume is %f", vol);
return;
}
There are a few issues with your code that are causing you to access out of your array bounds and to not read\write your circular buffer in the way intended.
I would suggest reading http://en.wikipedia.org/wiki/Circular_buffer to get a better understanding of circular buffers.
The main issues your code is suffering:
circular_pointer should be initialised to the delay amount (essentially the write head is starting at 0 so there is never any delay!)
playhead and circular_buffer are not updated between calls to process_data (circular_buffer is passed by value...)
playhead is reading from negative indices. The correct playhead calculation is
#define MAX_DELAY 44100
playhead++;
playhead = playhead%MAX_DELAY;
The second write to circular_buffer at the end of process_data is unnecessary and incorrect.
I would strongly suggest spending some time running your code in a debugger and closely watching what your playhead and circular_pointer are doing.
Mike
At least one problem is that you pass circular_pointer by value, not by reference. When you update it in the function, it's back to the same value next time you call the function.
I think you are on the right track, here, but if you want something that's structured a bit better, you might also want to checkout this answer:
how to add echo effect on audio file using objective-c
delay in sample can be put as 100 ms would be sufficient
I'm writing a little program in C, for check the HTML file have the right open and close tags?
but i've got some issues...
i have a file what contains the all possible tags, named tags.txt(those are only the first ones):
<a>
</a>
<abbr>
</abbr>
<area>
</area>
<aside>
</aside>
and i have the htmlfile.html, what I have to check:
<!--#echo var="date" -->
<area>
</area>
<area>
</area>
secondly, i want to replace the comments like this to the sysdate
like , the format is OK i can do it, but the prog puts in the file
this
my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_SIZE 512
void menu();
void check();
void datumos();
int main(int argc,char *argv[])
{
menu();
return 0;
}
void menu()
{
char menu[MAX_SIZE];
while(1 < 2)
{
printf("\npress a button:\n\n");
printf("\tFile HTML check..............:c\n");
printf("\t<!--#echo var="date" -->...........:d\n");
printf("\tExit:\tCTRL + C\n");
scanf("%s",menu);
if( strcmp(menu,"c") == 0 )
{
check();
}
else if( strcmp(menu,"d") == 0 )
{
datumos();
}
}
}
void check()
{
FILE *htmlfile;
FILE *checkfile;
htmlfile = fopen("htmlfile.html","w");
checkfile = fopen("tags.txt","r");
char line[MAX_SIZE];
char htmlline[MAX_SIZE];
char tags[189][30];
int i=0;
printf("\tcheck__1\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
int j;
for(j=0; j<sizeof(line); ++j)
{
tags[i][j]=line[j];
}
++i;
}
printf("\tcheck__2\n");
int k=0; char htmlfiletags[MAX_SIZE][30];
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
char currentline[sizeof(htmlline)];
int j=0;
if( currentline[j]=="<" )
{
while(currentline[j]!=">")
{
htmlfiletags[k][j]=currentline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
printf("\tcheck__3\n");
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
printf("\tcheck__4\n");
}
void copy_file(const char *from,const char *to)
{
FILE *fr;
FILE *t;
fr = fopen(from,"r");
t = fopen(to,"w");
char line[MAX_SIZE];
char row[MAX_SIZE];
while(fgets(line,sizeof(line),fr) != NULL)
{
sscanf(line,"%s",row);
fprintf(t,"%s\n",row);
}
fclose(fr);
fclose(t);
remove("tempfile.html");
}
void datumos()
{
time_t now = time(NULL);
struct tm *t = localtime(&now);
char date_time[30];
strftime( date_time, sizeof(date_time), "%x_%X", t );
FILE *htmlfile;
FILE *tempfile;
htmlfile = fopen("htmlfile.html","r");
tempfile = fopen("tempfile.html","w");
char line[MAX_SIZE];
//char datecomment[]="<!--#echo var=date -->";
while(fgets(line,sizeof(line),htmlfile) != NULL)
{
if( strcmp(line,"<!--#echo var="date" -->") == 0 )
{
char row[40];
strcpy(row,"<!--");
strcat(row, date_time);
strcat(row,"-->");
printf("%s",row);
fputs(row,tempfile);
}
else
{
fputs(line,tempfile);
}
}
fclose(htmlfile);
fclose(tempfile);
copy_file("tempfile.html","htmlfile.html");
}
it dies in this, in the inner for loop, in the if at the 200th check... i dont know why...
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
Thanks for all reply!!
G
Your code is very complicated, it has several issues.
Here's one:
for(j=0; j<sizeof(tags); ++j)
this will not do what I believe you expect; sizeof(tags) is not the array length of tags (which is declared as char tags[189][30];), it's the total size of the variable. So, this loop will go from 0 to 189 * 30 - 1, i.e. 5669, and thus index way out beyond the end of array.
Also, the idea to use sizeof here in any way is wrong, since the content of tags comes from a file and it thus impossible for the compiler to know. Remember that sizeof is evaluated at compile-time, for expressions like these.
You need to have a variable (e.g. size_t num_tags) that you increment for each line parsed from the tags file, and that you later use to iterate over tags.
Do not use regex, or some kind of string parsing, to parse HTML. Instead search the web, or this site, for a c library to parse html. Then check the parsed HTML file for the tags. This will ease the development a lot as you don't have to parse the files yourself.
i've fixed some things, but
- i still cant check the file's htmltags, dies at the same loop, i've fixed allocation of the tags array
- when in the htmlfile are 2 or more different comments and i'm replacing the comment the program replaces it with the sysdate, but the program copy the another comments badly, like =>
the code is now:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAX_SIZE 512
void menu();
void check();
void datumos();
int main(int argc,char *argv[])
{
menu();
return 0;
}
void menu()
{
char menu[MAX_SIZE];
while(1 < 2)
{
printf("\npress a button:\n\n");
printf("\tFile HTML check..............:c\n");
printf("\t<!--#echo var="date" -->...........:d\n");
printf("\tExit:\tCTRL + C\n");
scanf("%s",menu);
if( strcmp(menu,"c") == 0 )
{
check();
}
else if( strcmp(menu,"d") == 0 )
{
datumos();
}
}
}
void check()
{
FILE *htmlfile;
FILE *checkfile;
htmlfile = fopen("htmlfile.html","r");
checkfile = fopen("tags.txt","r");
char line[MAX_SIZE];
char htmlline[MAX_SIZE];
int i2=0;
printf("\tcheck__1\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
++i2;
}
char tags[i2][20];
int i=0;
printf("\tcheck__11\n");
while(fgets(line,sizeof(line),checkfile) != NULL)
{
int j;
for(j=0; j<sizeof(line); ++j)
{
tags[i][j]=line[j];
}
++i;
}
printf("\tcheck__2\n");
int k=0; char htmlfiletags[MAX_SIZE][30];
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
char currentline[sizeof(htmlline)];
int j=0;
if( currentline[j]=="<" )
{
while(currentline[j]!=">")
{
htmlfiletags[k][j]=currentline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
printf("\tcheck__3\n");
int n;
for(n=0; n<sizeof(htmlfiletags); ++n)
{
int j; int howmanytimesnot=0;
for(j=0; j<sizeof(tags); ++j)
{
//printf("\tcheck__3/1\n");
if(strcmp(htmlfiletags[n],tags[j])==0)
{
// printf("\t%d\n", howmanytimesnot);
++howmanytimesnot;
}
}
printf("\tcheck__3/3\n");
if(!(howmanytimesnot<sizeof(tags)))
{
printf("\tcheck__3/4\n");
printf("the file is not wellformed");
exit (1);
}
}
printf("\tcheck__4\n");
}
void copy_file(const char *from,const char *to)
{
FILE *fr;
FILE *t;
fr = fopen(from,"r");
t = fopen(to,"w");
char line[MAX_SIZE];
char row[MAX_SIZE];
while(fgets(line,sizeof(line),fr) != NULL)
{
sscanf(line,"%s",row);
fprintf(t,"%s\n",row);
}
fclose(fr);
fclose(t);
remove("tempfile.html");
}
void datumos()
{
time_t now = time(NULL);
struct tm *t = localtime(&now);
char date_time[30];
strftime( date_time, sizeof(date_time), "%x_%X", t );
FILE *htmlfile;
FILE *tempfile;
htmlfile = fopen("htmlfile.html","r");
tempfile = fopen("tempfile.html","w");
char line[MAX_SIZE];
char* datecomment="<!--#echo var=\"date\" -->";
while(fgets(line,sizeof(line),htmlfile) != NULL)
{
int i3; int db=0;
for(i3=0; i3<strlen(datecomment); ++i3)
{
if(line[i3]==datecomment[i3])
{
++db;
}
}
if(db==strlen(datecomment))
{
char row[30];
strcpy(row,"<!--");
strcat(row, date_time);
strcat(row,"-->\n");
fputs(row,tempfile);
}
else
{
fputs(line,tempfile);
}
}
fclose(htmlfile);
fclose(tempfile);
copy_file("tempfile.html","htmlfile.html");
}
the currentline it's not necessary,and i've fixed the compares too
while(fgets(htmlline,sizeof(htmlline),htmlfile) != NULL)
{
int j=0;
if( htmlline[j]=='<' )
{
while(htmlline[j]!='>')
{
htmlfiletags[k][j]=htmlline[j];
++j;
}
strcat(htmlfiletags[k][j+1],">");
++k;
}
}
-in addition, the another problem to replace only the suitable comments, and dont hurt the different ones still dont work
"so it replaces
<!--#echo var="date" --> to the sysdate, it's ok, but when there are different comments like
<!--#include something -->, it wont be copied back well, in the htmlfile will be only <!--#include"
ideas?
So, I am about 99% certain that I have implemented something wrong, but heres the deal.
I have been playing around with Grand Central Dispatch, and put together an experiment calculating MD5 hashes. I am running a macbook air with an i5, so have 4 cores available. This would led me to believe that using Grand Central Dispatch to calculate the hashes would be approx 4 times faster. But, for some reason, it appears to be slower.
Code below
Using GCD
#include <stdio.h>
#include <time.h>
#import <CommonCrypto/CommonDigest.h>
#import <dispatch/dispatch.h>
int main (int argc, const char * argv[])
{
int i,j,k,l,a;
int num_chars = 4, total;
clock_t start, end;
double elap;
printf("Calculating hashes for %d chars\n", num_chars);
total = num_chars ^ 64;
printf("Calculating %d hashes\n", total);
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_group_t group = dispatch_group_create();
start = clock();
printf("Starting calculation queue\n");
for(i=0;i<62;i++) {
for(j=0;j<62;j++) {
for(k=0;k<62;k++) {
for(l=0;l<62;l++) {
dispatch_group_async(group, queue, ^{
char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char buffer[10];
char out[100];
unsigned char hash[16];
sprintf(buffer, "%c%c%c%c", letters[i], letters[j], letters[k], letters[l]);
CC_MD5(buffer, strlen(buffer), hash);
});
}
}
}
}
printf("Finished calculation queue\n");
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
end = clock();
elap = ((double) end - start) / CLOCKS_PER_SEC;
printf("Time taken %2f\n", elap);
return 0;
}
Compile and run...
gcc -o a.out main.c
./a.out
Calculating hashes for 4 chars
Calculating 68 hashes
Starting calculation queue
Finished calculation queue
Time taken 35.193133
Looking at Activity Monitor, I can see all 4 cores max out while the script is running.
Now, comment out the dispatching....
#include <stdio.h>
#include <time.h>
#import <CommonCrypto/CommonDigest.h>
#import <dispatch/dispatch.h>
int main (int argc, const char * argv[])
{
int i,j,k,l,a;
int num_chars = 4, total;
clock_t start, end;
double elap;
printf("Calculating hashes for %d chars\n", num_chars);
total = num_chars ^ 64;
printf("Calculating %d hashes\n", total);
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_group_t group = dispatch_group_create();
start = clock();
printf("Starting calculation queue\n");
for(i=0;i<62;i++) {
for(j=0;j<62;j++) {
for(k=0;k<62;k++) {
for(l=0;l<62;l++) {
//dispatch_group_async(group, queue, ^{
char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char buffer[10];
char out[100];
unsigned char hash[16];
sprintf(buffer, "%c%c%c%c", letters[i], letters[j], letters[k], letters[l]);
CC_MD5(buffer, strlen(buffer), hash);
//});
}
}
}
}
printf("Finished calculation queue\n");
//dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
end = clock();
elap = ((double) end - start) / CLOCKS_PER_SEC;
printf("Time taken %2f\n", elap);
return 0;
}
Compile and run
gcc -o b.out main.c
./b.out
Calculating hashes for 4 chars
Calculating 68 hashes
Starting calculation queue
Finished calculation queue
Time taken 7.511273
Looking at Activity Monitor, it only shows 1 core active while the script runs.
There's probably too little work being done in the dispatch that it doesn't make the overhead involved with dispatching worthwhile. I would try and increase the amount of work done in each dispatch. I wouldn't have a clue whether this would help, but try:
Moving the dispatch up a few loops, perhaps wrap the k or j loop inside the dispatched block instead, to get it to do more work.
Remove the call sprintf and strlen. In fact, the block could be simplified to:
static const char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
unsigned char hash[16];
char buffer[4] = { letters[i], letters[j], letters[k], letters[l] };
CC_MD5(buffer, sizeof buffer, hash);