Grand central dispatch is giving me a slower execution time - c

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);

Related

problems utilitizing small pauses in c code using nanosleep

I am a C beginner and trying this and that.
I want to display a string letter by letter with tiny pauses in between. So my idea was a small pause using sleep or usleep after displaying each char but I read that using nanosleep in your own function makes more sense. So I put my little pauses in a function "msleep" to get microseconds pauses.
I output my string 3 times.
Once in the main(), then in a do-while-loop in a function (fancyOutput) char by char, and eventually in the same function with printf again to check, if it was handled over correctly.
My problem: I expected, that the middle output would work char by char and separated by 100/1000 seconds breaks, but what I experience is a long break before chowing any char and then a fast output if line two and three. It looks like the compiler "realized what I am planning to do and wants to modify the code to be more efficient." So all my pauses seemed to be combined in one long break.
Maybe you remeber the captions in the tv series "x files" - something like that I want to produce.
For sure there are better and more sophisticated ways to archieve what I am going to try but I want to learn and understand what is going on. Can someone help me with that?
I am using codeclocks on a debian-based distro with gcc.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int msleep(long tms);
void fancyOutput(char inputToOutput[]);
int msleep(long tms)
{
struct timespec ts;
int ret;
if (tms < 0)
{
return -1;
}
ts.tv_sec = tms / 1000;
ts.tv_nsec = (tms % 1000) * 1000000;
do
{
// printf("sleeping for %d", ret);
ret = nanosleep(&ts, &ts);
}
while (ret);
return ret;
}
void fancyOutput(char inputToOutput[])
{
int counter = 0;
do
{
printf("%c", inputToOutput[counter]);
msleep(100);
++counter;
}
while (!(inputToOutput[counter]=='\0'));
printf("\n");
printf("%s\n", inputToOutput); // only check, if string was properly handled over to function
}
char output[] = "This string shall appear char by char in the console.";
void main(void)
{
printf("%s\n", output); // only check, if string was properly set and initialized
fancyOutput(output); // here the function above is called to output the string char by cchar with tiny pauses between
}
You are getting problem with buffer.
When you use printf with no \n (new line) C is buffering the display in order to display information block by block (to optimize displaying speed).
Then you need to either add a \n to your printf or add a flush of the stdout.
An other solution will be to use stderr, which got no buffer, but stderr is meant for error not output :)
You can also check setvbuf in order to change the buffering.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int msleep(long tms);
void fancyOutput(char inputToOutput[]);
int msleep(long tms)
{
struct timespec ts;
int ret;
if (tms < 0)
{
return -1;
}
ts.tv_sec = tms / 1000;
ts.tv_nsec = (tms % 1000) * 1000000;
do
{
// printf("sleeping for %d", ret);
ret = nanosleep(&ts, &ts);
}
while (ret);
return ret;
}
void fancyOutput(char inputToOutput[])
{
int counter = 0;
do
{
printf("%c", inputToOutput[counter]);
flush(stdout);
msleep(100);
++counter;
}
while (!(inputToOutput[counter]=='\0'));
printf("\n");
printf("%s\n", inputToOutput); // only check, if string was properly handled over to function
}
char output[] = "This string shall appear char by char in the console.";
void main(void)
{
printf("%s\n", output); // only check, if string was properly set and initialized
fancyOutput(output); // here the function above is called to output the string char by cchar with tiny pauses between
}
So, I tried the solution to place fflush(stdout); directly after the char-output in the loop. It worked as intended.
Summarizing for those with similar problems (guess this also happens with usleep and similar self-made functions):
As I understaood, printf "collects" data in stdout until it "sees" \n, which indicates the end of a line. Then printf "releases" stdout. So in my initial post it "kept" each single char in stdout, made a pause after each char and finally released stdout in one fast output.
So fflush(stdout); after each char output via empties stdout char by char.
Hope it can help others.

C gettimeofday Doesn't Work Properly With GoLang

I've a simple C function which I call from GoLang. In my C function I'm using gettimeofday function. I understand that this function doesn't give accurate time and I'm okay with that as I only need to get some idea. I just want to get the time difference to run a big for loop.When I run the C function from a C program, it works fine. The for loop takes around 3 seconds to finish. But if I call the same function from GoLang, it looks like that it doesn't take any time in the for loop The program finishes immediately.
Here goes my code.
timetest.h
#include <sys/time.h>
#include<stdio.h>
int TimeTest(){
int i=0;
int j = 1000000000;
unsigned long long startMilli=0;
unsigned long long endMilli=0;
struct timeval te;
gettimeofday(&te, NULL);
startMilli = te.tv_sec*1000LL + te.tv_usec/1000;
for (i=0; i<1000000000; i++){
if (j-1 == i){
printf("matched\n");
}
}
gettimeofday(&te, NULL);
endMilli = te.tv_sec*1000LL + te.tv_usec/1000;
printf("Start = %d End = %d Total time %d\n", startMilli, endMilli, endMilli - startMilli);
return endMilli - startMilli;
}
test.go
package main
// #include <sys/time.h>
// #include "timetest.h"
import "C"
import (
"fmt"
)
func main(){
diff := C.TimeTest()
fmt.Println(diff)
}
Main.c
#include"timetest.h"
int main(){
int diff = TimeTest();
printf("%d\n", diff);
return 0;
}

audio delay making it work

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

completely remove function call at runtime in C

Is it possible to completely remove function call from C code at runtime and insert it back when needed.
I'm not sure if ELF can be modified at run time, so that no cpu cycle is wasted incase of no use of function.
I don't want to place a 'if' check before the function call to avoid calling a function.
For example if global flag g_flg=1 then func1 should look like below
void func1(int x)
{
/* some processing */
func2(y);
/* some processing */
}
if global g_flag=0 then func1 should look like below
void func1(int x)
{
/* some processing */
/* some processing */
}
Don't optimize something that doesn't need it. Have you tried assessing the potential improvement on your performance?
Try setting g_flg to 1 and execute this:
if (g_flg == 1) {func2(y);}
Then try executing this:
func2(y);
Both 1 million times (or whatever number of times you can run it in a reasonable time). I'm quite sure you'll notice there is virtually no difference between both things.
Plus, apart from that, I think what you want to do is impossible, because ELF is a binary (compiled) format.
What you could probably get away with doing instead would be something like this:
struct Something;
typedef struct Something Something;
int myFunction(Something * me, int i)
{
// do a bunch of stuff
return 42; // obviously the answer
}
int myFunctionDoNothing(Something * dummy1, int dummy2)
{
return 0;
}
int (*function)(Something *, int) = myFunctionDoNothing;
// snip to actual use of function
int i;
function = myFunctionDoNothing;
for (i = 0; i < 100000; ++i) function(NULL, 5 * i); // does nothing
function = myFunction;
for (i = 0; i < 100000; ++i) function(NULL, 5 * i); // does something
WARNING
This might be a premature optimization. Depending on how your compiler treats this and how your cpu handles branching, you might actually lose performance this way as opposed to the naive way (stopping it in the function with a flag)
On most desktop and server architectures branching is faster than indirect calls, since they do branch prediction and/or speculative execution. I have never heard of an architecture where indirect call is faster than a single branch. (Jump tables, for switch() statements, have more than one branch, and are therefore a different thing altogether.)
Consider the following microbenchmark I threw together. test.c:
/* test.c */
volatile long test_calls = 0L;
volatile long test_sum = 0L;
void test(long counter)
{
test_calls++;
test_sum += counter;
}
work.c:
/* work.c */
void test(long counter);
/* Work function, to be measured */
void test_work(long counter, int flag)
{
if (flag)
test(counter);
}
/* Dummy function, to measure call overhead */
void test_none(long counter __attribute__((unused)), int flag __attribute__((unused)) )
{
return;
}
and harness.c:
#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
/* From test.c */
extern volatile long test_calls;
extern volatile long test_sum;
/* Dummy function, to measure call overhead */
void test_none(long counter, int flag);
/* Work function, to be measured */
void test_work(long counter, int flag);
/* Timing harness -- GCC x86; modify for other architectures */
struct timing {
struct timespec wall_start;
struct timespec wall_stop;
uint64_t cpu_start;
uint64_t cpu_stop;
};
static inline void start_timing(struct timing *const mark)
{
clock_gettime(CLOCK_REALTIME, &(mark->wall_start));
mark->cpu_start = __builtin_ia32_rdtsc();
}
static inline void stop_timing(struct timing *const mark)
{
mark->cpu_stop = __builtin_ia32_rdtsc();
clock_gettime(CLOCK_REALTIME, &(mark->wall_stop));
}
static inline double cpu_timing(const struct timing *const mark)
{
return (double)(mark->cpu_stop - mark->cpu_start); /* Cycles */
}
static inline double wall_timing(const struct timing *const mark)
{
return (double)(mark->wall_stop.tv_sec - mark->wall_start.tv_sec)
+ (double)(mark->wall_stop.tv_nsec - mark->wall_start.tv_nsec) / 1000000000.0;
}
static int cmpdouble(const void *aptr, const void *bptr)
{
const double a = *(const double *)aptr;
const double b = *(const double *)bptr;
if (a < b)
return -1;
else
if (a > b)
return +1;
else
return 0;
}
void report(double *const wall, double *const cpu, const size_t count)
{
printf("\tInitial call: %.0f cpu cycles, %.9f seconds real time\n", cpu[0], wall[0]);
qsort(wall, count, sizeof (double), cmpdouble);
qsort(cpu, count, sizeof (double), cmpdouble);
printf("\tMinimum: %.0f cpu cycles, %.9f seconds real time\n", cpu[0], wall[0]);
printf("\t5%% less than %.0f cpu cycles, %.9f seconds real time\n", cpu[count/20], wall[count/20]);
printf("\t25%% less than %.0f cpu cycles, %.9f seconds real time\n", cpu[count/4], wall[count/4]);
printf("\tMedian: %.0f cpu cycles, %.9f seconds real time\n", cpu[count/2], wall[count/2]);
printf("\t75%% less than %.0f cpu cycles, %.9f seconds real time\n", cpu[count-count/4-1], wall[count-count/4-1]);
printf("\t95%% less than %.0f cpu cycles, %.9f seconds real time\n", cpu[count-count/20-1], wall[count-count/20-1]);
printf("\tMaximum: %.0f cpu cycles, %.9f seconds real time\n", cpu[count-1], wall[count-1]);
}
int main(int argc, char *argv[])
{
struct timing measurement;
double *wall_seconds = NULL;
double *cpu_cycles = NULL;
unsigned long count = 0UL;
unsigned long i;
int flag;
char dummy;
if (argc != 3 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s COUNT FLAG\n", argv[0]);
fprintf(stderr, "\n");
return 1;
}
if (sscanf(argv[1], " %lu %c", &count, &dummy) != 1) {
fprintf(stderr, "%s: Invalid COUNT.\n", argv[1]);
return 1;
}
if (count < 1UL) {
fprintf(stderr, "%s: COUNT is too small.\n", argv[1]);
return 1;
}
if (!(unsigned long)(count + 1UL)) {
fprintf(stderr, "%s: COUNT is too large.\n", argv[1]);
return 1;
}
if (sscanf(argv[2], " %d %c", &flag, &dummy) != 1) {
fprintf(stderr, "%s: Invalid FLAG.\n", argv[2]);
return 1;
}
wall_seconds = malloc(sizeof (double) * (size_t)count);
cpu_cycles = malloc(sizeof (double) * (size_t)count);
if (!wall_seconds || !cpu_cycles) {
free(cpu_cycles);
free(wall_seconds);
fprintf(stderr, "Cannot allocate enough memory. Try smaller COUNT.\n");
return 1;
}
printf("Call and measurement overhead:\n");
fflush(stdout);
for (i = 0UL; i < count; i++) {
start_timing(&measurement);
test_none(i, flag);
stop_timing(&measurement);
wall_seconds[i] = wall_timing(&measurement);
cpu_cycles[i] = cpu_timing(&measurement);
}
report(wall_seconds, cpu_cycles, (size_t)count);
printf("\n");
printf("Measuring FLAG==0 calls: ");
fflush(stdout);
test_calls = 0L;
test_sum = 0L;
for (i = 0UL; i < count; i++) {
start_timing(&measurement);
test_work(i, 0);
stop_timing(&measurement);
wall_seconds[i] = wall_timing(&measurement);
cpu_cycles[i] = cpu_timing(&measurement);
}
printf("%ld calls, sum %ld.\n", test_calls, test_sum);
report(wall_seconds, cpu_cycles, (size_t)count);
printf("\n");
printf("Measuring FLAG==%d calls:", flag);
fflush(stdout);
test_calls = 0L;
test_sum = 0L;
for (i = 0UL; i < count; i++) {
start_timing(&measurement);
test_work(i, flag);
stop_timing(&measurement);
wall_seconds[i] = wall_timing(&measurement);
cpu_cycles[i] = cpu_timing(&measurement);
}
printf("%ld calls, sum %ld.\n", test_calls, test_sum);
report(wall_seconds, cpu_cycles, (size_t)count);
printf("\n");
printf("Measuring alternating FLAG calls: ");
fflush(stdout);
test_calls = 0L;
test_sum = 0L;
for (i = 0UL; i < count; i++) {
start_timing(&measurement);
test_work(i, i & 1);
stop_timing(&measurement);
wall_seconds[i] = wall_timing(&measurement);
cpu_cycles[i] = cpu_timing(&measurement);
}
printf("%ld calls, sum %ld.\n", test_calls, test_sum);
report(wall_seconds, cpu_cycles, (size_t)count);
printf("\n");
free(cpu_cycles);
free(wall_seconds);
return 0;
}
Put the three files in an empty directory, then compile and build ./call-test:
rm -f *.o
gcc -W -Wall -O3 -fomit-frame-pointer -c harness.c
gcc -W -Wall -O3 -fomit-frame-pointer -c work.c
gcc -W -Wall -O3 -fomit-frame-pointer -c test.c
gcc harness.o work.o test.o -lrt -o call-test
On AMD Athlon II X4 640, using gcc-4.6.3 (Xubuntu 10.04), running
./call-test 1000000 1
tells me that the overhead is just 2 clock cycles (< 1ns) for the test alone (branch not taken), and just 4 clock cycles (just over a nanosecond) when calling the second function which increases test_calls and adds the counter to test_sum.
When omitting all optimizations (use -O0 and leave out -fomit-frame-pointer when compiling), the test alone costs about 3 clock cycles (3 cycles if branch not taken), and about 9 cycles if the branch is taken and the work is done to update the two extra variables.
(The two extra variables let you easily see that the harness does actually do all it should do; they're just an extra check. And I wanted to have some work in the second function, so the timing differences would be easier to spot.)
The above interpretation is only valid for the case when the code is already cached; i.e. run recently. If the code is run only rarely, it won't be in cache. However, then the test overhead matters even less. Caching effects -- for example, if "nearby" code has been run (you can see this for the call overhead measurement, the other test functions code' tends to get cached too!) -- are much larger anyway. (While the test harness does produce the initial call results separately, don't put too much faith in it, since it does not try to clear any caches in any way.)
My conclusion is that adding
if (flag)
debug_function_call();
to any normal code is perfectly fine: the overhead is literally neglible; practically irrelevant. As always, consider the overall algorithm instead. Any enhancements in the algorithm yield much bigger rewards than worrying about the code the compiler generates.
(Since I wrote the test code above at one sitting, there are likely some bugs and/or brainfarts in them. Check, and if you find any, let me know below so I can fix the code.)

output transfer to a new file

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

Resources