Calling the value of a function inside another function C - c

I'm trying to implement my own algorithm for a brute-force program in C but I can't figure out what I'm facing at a certain point. Here's the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define CHUNK 1024
void combinations(char nums[],char candidate[],int current_len,int n3,int len) {
if(current_len == len) {
printf("%s\n", candidate);
return;
}
else {
int i;
for(i=0; i < n3; i++) {
candidate[current_len] = nums[i];
combinations(nums,candidate,current_len+1,n3,len);
}
}
}
int main() {
// ---- Reading the data from ASCII text ----
int match[32];
int length;
char buf[CHUNK];
FILE *file;
size_t nread;
file = fopen("data.txt", "r");
if(file) {
while((nread = fread(buf,1,sizeof buf, file)) > 0) {
fwrite(buf,1,nread,stdout);
match[32] = nread;
length = nread-1;
printf("\n%d\n", length);
}
fclose(file);
}
// -------------------------------------------
char lc_letters[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v'};
char up_letters[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V'};
char nums[] = {'0','1','2','3','4','5','6','7','8','9'};
char candidate[32];
char output[32];
int n = sizeof(lc_letters)/sizeof(lc_letters[0]);
int n2 = sizeof(up_letters)/sizeof(up_letters[0]);
int n3 = sizeof(nums)/sizeof(nums[0]);
int count = length;
char arr[10] = "";
char new_str[21];
combinations(nums,arr,0,n3,count);
}
Now let me explain this: what I'm trying to do is to read the text data from a file (OK here, it works) and then to do all the possible combinations of words or numbers. In this case I just created the combinations of the numbers in order to see if it works with one case and then go on like that with the others, but it's not like that. I can create my combinations with the void function called "combination" but here comes the problem:
Now I have both the data text and the combinations created, I can't figure out how to compare the data text with each combination created and print "YES" if it matches or "NO" if it doesn't.
For example: this code reads the data text which is "12", so a text with length 2. Then the program creates all the combinations of numbers from 0 to 9 with length 2, so from 00 to 99.
Now, can someone help me with this? I know it's not one of the best way to implement this algorithm but it's my own idea and I don't want to copy the one of another person.

Related

How do you assign structs into an array?

I have currently made this much of the code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#define STRSIZE 21
struct PInven{
int count;
struct PItem{
char name[STRSIZE];
int amount;
}Pitem;
}Pinven;//this needs to be an output file
int ReadInProduce (){
//read in file and check to see if the file exist or not.
FILE * PinFile = fopen("produce.txt","r");
if (PinFile == NULL){
printf("ERROR: WRONG FILE");
}
else{
printf("I did it!!\n");
}
//assigning the value gotten into the struct variable(but need to maybe change this since it needs to be an output)
fscanf(PinFile,"%d",&Pinven.count);
printf("%d\n", Pinven.count);
int i;
for(i =0; i <Pinven.count; i++){
fscanf(PinFile,"%20s %d",Pinven.Pitem.name, &Pinven.Pitem.amount);
printf("%s %d\n",Pinven.Pitem.name, Pinven.Pitem.amount);
}
//making an array to hold the variables
//FILE * PoutFile = fopen("produce_update.txt","w");
fclose(PinFile);
return 0;
}
From there I want to get the file that is read to the structs to be printed out into an array so that later on I can make a function that will be able to compare to the to it.
Basically a store management system. Where the file of the inventory is read in and compared to the file that is store and return a new value for the amount of produce now either left or gained.
10 //number of items that will be stored in the store
apple 19
banana 31
broccoli 9
...
In general, it's a really bad idea to include header information in the file about the number of entries in the file. You want to be able to do stream processing, and that will be more difficult if you need that meta-data. More importantly, it is important to understand how to write the code so that you don't need it. It's not really that difficult, but for some reason people avoid it. One simple approach is just to grow the array for each entry. This is horribly inefficient, but for the sake of simplicity, here's an example that expects the file not not include that first line:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <limits.h>
#define STRSIZE 128
struct PItem{
char name[STRSIZE];
int amount;
};
struct PInven{
int count;
struct PItem *PItem;
};
static void
grow(struct PInven *p)
{
p->PItem = realloc(p->PItem, ++p->count * sizeof *p->PItem);
if( p->PItem == NULL ){
perror("out of memory");
exit(1);
}
}
int
ReadInProduce(struct PInven *P, const char *path)
{
FILE * PinFile = fopen(path, "r");
if( PinFile == NULL ){
perror(path);
exit(1);
}
char fmt[64];
int max_len;
max_len = snprintf(fmt, 0, "%d", INT_MAX);
snprintf(fmt, sizeof fmt, "%%%ds %%%dd", STRSIZE - 1, max_len - 1);
grow(P);
struct PItem *i = P->PItem;
while( fscanf(PinFile, fmt, i->name, &i->amount) == 2 ){
i += 1;
grow(P);
}
P->count -= 1;
fclose(PinFile); /* Should check for error here! */
return P->count;
}
int
main(int argc, char **argv)
{
struct PInven P = {0};
char *input = argc > 1 ? argv[1] : "produce.txt";
ReadInProduce(&P, input);
struct PItem *t = P.PItem;
for( int i = 0; i < P.count; i++, t++ ){
printf("%10d: %s\n", t->amount, t->name);
}
}
As an exercise for the reader, you should add some error handling. At the moment, this code simply stops reading the input file if there is bad input. Also, it would be a useful exercise to do fewer reallocations.
you should change Structure of PInven to it can save a dynamic array of Pitem with a Pitem pointer.
tested :
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define STRSIZE 21
typedef struct {
char name[STRSIZE];
int amount;
} Pitem;
struct PInven {
int count;
Pitem *pitem;
} Pinven; // this needs to be an output file
int main() {
// read in file and check to see if the file exist or not.
FILE *PinFile = fopen("produce.txt", "r");
if (PinFile == NULL) {
printf("ERROR: WRONG FILE");
} else {
printf("I did it!!\n");
}
// assigning the value gotten into the struct variable(but need to maybe
// change this since it needs to be an output)
fscanf(PinFile, "%d", &Pinven.count);
Pinven.pitem = (Pitem *)malloc(sizeof(Pitem) * Pinven.count);
printf("%d\n", Pinven.count);
int i;
for (i = 0; i < Pinven.count; i++) {
fscanf(PinFile, "%20s %d", Pinven.pitem[i].name,
&Pinven.pitem[i].amount);
// printf("%s %d\n",Pinven.pitem[i].name, Pinven.pitem[i].amount);
}
for (i = 0; i < Pinven.count; i++) {
printf("%s %d\n", Pinven.pitem[i].name, Pinven.pitem[i].amount);
}
// making an array to hold the variables
// FILE * PoutFile = fopen("produce_update.txt","w");
fclose(PinFile);
// remember free
free(Pinven.pitem);
return 0;
}

C function returning different values while calling from main function

I have written a program which read values from a the file. The data in the file is in following format.
100 Full Name SomeDetails.
234 Full Name SomeDetails
Following is the program which i wrote.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAX 10
struct student
{
int rollno;
char name[20];
char course[25];
};
int main()
{
FILE *fptr;
fptr=fopen("records.txt","r");
struct student s[10];
int i=0,tstudent=0;
char che;
char line[100];
//SECTION : 1.1 -> READING NUMBER OF LINES
while(!feof(fptr))
{
che=fgetc(fptr);
if(che=='\n')
{
tstudent++;
}
}
printf("Total Lines in File = %d\n",tstudent);
fclose(fptr);
//SECTION : 1.2 -> READING RECORDS FROM FILE
fptr=fopen("records.txt","r");
char newString[20][20];
int ii,j,ctr;
j=0;
ctr=0;
for(i=0; i<tstudent; i++)
{
fgets(line,100,fptr);
printf("Value of Line %d = %s",i,line);
for(ii=0; ii<=(strlen(line)); ii++)
{
// if tab or NULL found, assign NULL into newString[ctr]
if(line[ii]=='\t'||line[ii]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=line[ii];
j++;
}
}
}
for(ii=0; ii < ctr; ii++)
{
printf("\n%s",newString[ii]);
}
printf("Value of ctr = %d",ctr);
fclose(fptr);
}
Above code is working fine, BUT all the code is in main function, but i want to make a separate function which can be called from main file and return me every data of file in two dimensional or one dimensional array as return value.
Any help/suggestions would be appreciated.
I tried following CODE as a separate function.. NOT WORKING.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
char readfile(int tstudent,FILE* filename)
{
//FUNCTION TO READ RECORDS FROM FILE.
FILE *fptr;
int i,k;
char line[100];
char newString[20][20];
int j=0,ctr=0;
fptr=fopen("records.txt","r");
for(i=0; i<tstudent; i++)
{
fgets(line,100,fptr);
printf("Value of Line %d = %s",i,line);
for(k=0; k<=(strlen(line)); k++)
{
// if tab or NULL found, assign NULL into newString[ctr]
if(line[k]=='\t'||line[k]=='\0')
{
newString[ctr][j]='\0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=line[k];
j++;
}
}
}
return newString;
}
I defined a new variable char results[] in main function.. and tried to called the function as follows
results[]=readfile(tstudent,fptr)
but when trying to read results.. its showing garbage
char readfile(int tstudent,FILE* filename)
...
char newString[20][20];
...
return newString;
That can't be a good thing, right? You define readFile to return one single character (not a pointer, just one byte) and then return an array instead. We should not be surprised the compiler complained.
If you "fix" that be redefining the return type, you still have a problem because newString is an automatic local variable. The storage (memory) it defines is undefined outside the function.
The easiest way for a function to populate a structure (or array) in C is for the caller to pass it as a function parameter. So you wind up with something more like:
int readfile( FILE* input, char newString[][20], int tstudent )
where newString is defined the same way as you have it, but by the caller, not in readfile. Cf. the stdio functions like fgets; most of them require the caller to define the buffer they read into.
I'll just point out a few more mistakes.
Whenever you call a function -- especially an I/O function -- check for errors. You may want to read tstudent records, but how many are there? If you ask for 5 and find only 1, what then? Your read loop must test for end-of-file, and readfile must return the number of records read, else the caller will never know. Compare with how fread(3) works. Those Unix guys knew a thing or two about how to define a function!
Now your function looks something like this:
int readfile( FILE* input, char newString[][20], int tstudent ) {
char line[100], *s;
int i=0;
for( ; i < tstudent && (s = fgets(line, sizeof(line), input)) != NULL; i++ ) {
/* do stuff with line */
}
/* check for EOF/error if s is NULL, and report */
return i;
}

Creating an array with unknown size of input files

I newer in C language. I could not solve my problem. I have a input file, let's say input.txt. We know there are 4 column on every line. Nevertheless, we do not know how many lines are there. I give you sample input.txt:
Student,James,12,65
Teacher,Jane,23,60
Teacher,Michael,30,75
Student,Erric,15,73
First column can be 2 different things like student or teacher. 2nd column will be unique. No repeated names. 3rd column will be ages of the person's. 4th column will be weights. Also, I am trying to make 2D array. So, my goal is:
arrName = {{Student, James, 12, 65}, {Teacher,Jane,23,60}, {Teacher,Michael,30,75}, {Student, Erric, 15,73}}
I am trying to create like this array. The array must be dynamically. because we do not know how many lines are there. I could not split the every line by commas. I have tried strdot. how can I parse the lines with comma, and add them into 2D array? Also, I got confused about pointers. While creating 2D array, do we have to use like char **arrPtr;? Or using like *arrPtr is enough for creating 2D array?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COLUMN 4 //We know that there are 4 column in chars.txt file.
int main(int argc, char const *argv[]) {
char *arrName;
int nameLines;
arrName = (char *) malloc( sizeof( char ) );
FILE *FileName;
FileName = fopen(argv[1], "r");
if (FileName == NULL) {
printf("The Name file could not open!\n");
exit(0);
}
else{
char c;
while ( (c == fgetc(FileName)) != EOF ) {
if (c == '\n') {
nameLines++;
}
}
printf("%d\n", nameLines);
}
return 0;
}
I could not continue after else statement. Can you help me?
You got a bunch of errors in your code like this for example.
while ( (c == fgetc(FileName)) != EOF ) { -> Comparison of constant -1 with boolean expression is always true
So let's start fresh. This is how I would read a comma separated file and dynamically allocate memory to an array of ´read´ objects. It's actually less lines of code then you would expect.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define COLUMNS 4
#define MAX_STRING_LENGTH 100 //Enter the maximum characters allowed as profession and name
typedef struct theDAta{
char type[MAX_STRING_LENGTH+1];
char name[MAX_STRING_LENGTH+1];
unsigned int age;
unsigned int weight;
}theData;
int main(int argc, char const *argv[]) {
theData* allDataPtr=malloc(1); //Pointer to all entries
theData currentData; //The current read data
int currentBlock=0; //the index currently 'active'
FILE *fp = fopen(argv[1], "r");
if (!fp) {
printf("The file you provided can't be read!\n");
exit(EXIT_FAILURE);
}
while (fscanf(fp, "%[^,],%[^,],%d,%d\n", currentData.type, currentData.name,&currentData.age,&currentData.weight) == COLUMNS) {
allDataPtr=realloc(allDataPtr, sizeof(theData)*(currentBlock+1));
if (!allDataPtr) {exit(EXIT_FAILURE);} //Memory allocation failure. Ok so here i lost my pointer to the previous memory.. However we let the OS garbage collect us.
memcpy(allDataPtr+currentBlock++, &currentData, sizeof(currentData));
}
for (int x=0; x<currentBlock; x++) {
printf("Profession: %s\nName: %s\nAge: %d\nWeight: %d\n\n",allDataPtr[x].type,allDataPtr[x].name,allDataPtr[x].age,allDataPtr[x].weight);
}
fclose(fp);
free(allDataPtr);
return 0;
}
So what I do is to create a struct containing the stuff I want to populate from the file. Then I populate that object and extend the memory with the size of that object and then copy the read data to the end of that memory block.. That's basically it... Hope you get great grades :) !!
/Anders
EDIT
Was a bit bored this evening, so let's shave the code... And humm, well. This is not part of my official answer :-) but you could bling it like this (it's actually also skipping one layer of memory copy :) and the engine is 3 lines of C code if you define a line of C code delimiter as ';'->
typedef struct j{
char t[MAX_STRING_LENGTH+1];
char n[MAX_STRING_LENGTH+1];
unsigned int a;
unsigned int w;
}j;
int main(int argc, char const *argv[]) {
j* g;
int l=0;
FILE *h;
if((!(h=fopen(argv[1],"r"))||(!(g=malloc(sizeof(j))))))exit(-1);
while(fscanf(h,"%[^,],%[^,],%d,%d\n",g[l].t,g[l].n,&g[l].a,&g[l].w)==COLUMNS)if(!(g=realloc(g,sizeof(j)*(++l+1))))exit(-1);
for(int x=0;x<l;x++)printf("Profession: %s\nName: %s\nAge: %d\nWeight: %d\n\n",g[x].t,g[x].n,g[x].a,g[x].w);
fclose(h);
free(g);
return 0;
}

C - create members of struct in loop?

I am new to C programing and want to write a program that reads a line of integers and then creates a member of a struct for each of them. Here is a simplified example:
Let’s say this is the line: *23 4 12 56 78 *
and the struct looks like this:
struct structure
{
int index;
int number;
};
The first member should look like this:
struct structure member0;
member0.index = 0;
member0.number = 23;
But I want the program to be able to read lines of any length, so I want a loop that, whenever an integer is read, creates a new member using the number read and a counter that sets the name and index to previous index + 1 and I would like to know if and how it is possible to do so.
It can be done
Use fgets() to read the line
Break the line into tokens using strtok()
Convert each token to integer using atoi() or strtol()
Keep some variable say i which you need to increment for each token and should be reset after each fgets() call
Have dynamic or static array of your structure to hold the above information
Use strtol(), you'd want something along this line..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define MAX_SIZE 100
typedef struct _TMember
{
int index;
int number;
} TMember;
int main()
{
TMember arr[MAX_SIZE] = {};
char szNumbers[] = "10 20 30 40 50";
char *pEnd;
long int li;
unsigned short index = 0;
pEnd = szNumbers;
for( ; ; )
{
char *tmp = pEnd;
li = strtol( pEnd, &pEnd, 10 );
if( tmp == pEnd )
{
break;
}
else
{
arr[index].index = index;
arr[index].number = li;
index++;
}
}
for( int i = 0; i < index; i++ )
{
printf( "Member %d, idx = %d, number = %d\n", i, arr[i].index, arr[i].number );
}
return 0;
}

How do I get this to decode (Perl cbc-crypt to C cbc_crypt conversion)

I'm trying to be able to decode encoded strings that were encoded using a perl script. The reason I can't just change the perl script is because a lot of important data already exists that was saved via the perl script and it would be too much to decode in perl and recode another way. It's easier just to keep things in place (for now). However, the compiled perl code is 2MB. I want to write it in C so the executable will be a smaller size.
What I have so far is below. It won't work though. It basically gives me junk output. The problem I think is that the perl script used a hex-based encryption. How do I go about decoding that? Can someone point me to where I went wrong?
/*
Test to decode perl-encrypted string.
NOTE: Not all code written by me. Function code is either written by or derived
from code from other people in response to similar questions found on the
internet.
Required Lib: crypt (-lcrypt)
Perl Code from existing script (that is being converted to C):
use Crypt::CBC;
use Crypt::DES;
my $text = "thisisalongtest";
my $salt_key = "fOagmJOKu2SF";
my $cipher = Crypt::CBC->new( -key => $salt_key, -cipher => 'DES' -header => 'none');
my $enc_text = $cipher->encrypt_hex($text);
Perl crypt functions require libcrypt-cbc-perl & libcrypt-des-perl
Data:
Original Text: thisisalongtest
Salt Key: fOagmJOKu2SF
Resulting Encrypted String: 53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1
Resulting output:
Decrypted: (unprintable junk characters)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/des_crypt.h>
#define BUFFSIZE 420
int encrypt(char key[9], char salt[9], char pass[BUFFSIZE], int mode);
void enc_from_hex(const char* st, char ret_result[BUFFSIZE]);
int hex_to_int(char c);
int hex_to_ascii(char c, char d);
int main (int argc, char *argv[]) {
int err;
char passwd[BUFFSIZE];
char result[BUFFSIZE];
char key[13];
sprintf(key,"fOagmJOKu2SF");
/* Change this from hex pairs to ASCII */
sprintf(passwd, "53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1");
enc_from_hex(passwd, result);
/* Decrypt */
err = encrypt(key, "", result, 1); /* DO NOT use 'NULL' for 2nd parameter! */
if(err != 0) {
printf("Error.\n");
} else {
printf("Decrypted: %s\n", result);
}
return 0;
}
/* Encryption */
int encrypt(char key[13], char salt[13], char pass[BUFFSIZE], int mode){
char temp[13];
strcpy(temp, salt);
int buffsize;
int errcode;
des_setparity(key);
buffsize = strlen(pass);
/* Pad pass to ensure size is divisable by 8.*/
while (buffsize % 8 && buffsize<BUFFSIZE) {
pass[buffsize++] = '\0';
}
/* Determine Function */
if(mode == 1) {
errcode = cbc_crypt(key, pass, buffsize, DES_DECRYPT | DES_SW, temp);
} else {
errcode = cbc_crypt(key, pass, buffsize, DES_ENCRYPT | DES_SW, temp);
}
if (DES_FAILED(errcode) || strcmp(pass, "") == 0) {
return errcode;
}
return errcode;
}
/* Hex conversion functions */
void enc_from_hex(const char* st, char ret_result[BUFFSIZE]) {
char temp[2];
int length = strlen(st);
int i;
char buf = 0;
for(i = 0; i < length; i++) {
if(i % 2 != 0) {
sprintf(temp, "%c", hex_to_ascii(buf, st[i]));
strcat(ret_result, temp);
} else {
buf = st[i];
}
}
}
int hex_to_int(char c) {
int first = c / 16 - 3;
int second = c % 16;
int result = first*10 + second;
if(result > 9) result--;
return result;
}
int hex_to_ascii(char c, char d) {
int high = hex_to_int(c) * 16;
int low = hex_to_int(d);
return high+low;
}
As #ikegami points out in the comments the value passed to key Crypt::CBC is not really a key. This value is passed to another function which combines it with a random salt then hashes it to generate the real key and initialization vector. The random salt is saved with the cypher text the idea being if you encrypt the same data with the same key more than once the output will be different every time.
If you convert your encrypted string to ascii you will notice the first eight characters spell Salted__, this corresponds to the format used by OpenSSL.
See below for a somewhat crude example using OpenSSL's EVP api:
//
// compile with: gcc -o crypt crypt.c -lssl -lcrypto
//
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
int main(int argc, char *argv[]){
char pass[]="fOagmJOKu2SF";
char text[]="53616c7465645f5f167ebac84042fe7ceac836e1d3e7d3aa1dfc27e0e8cad0f1";
int i = 0;
char *pos=text;
while(*pos){ // converts hex string to binary in place
sscanf(pos, "%2hhx", &text[i++]);
pos += 2;
} text[i]=0;
EVP_CIPHER_CTX ctx;
unsigned char key[8] = {0};
unsigned char iv[8] = {0};
int len;
char *clear = malloc(strlen(text));
// v-> First Charicter after 'Salted__'
EVP_BytesToKey(EVP_des_cbc(), EVP_md5(), &text[8], pass, strlen(pass), 1, key, iv);
EVP_DecryptInit(&ctx, EVP_des_cbc(), key, iv);
// v-> Cypertext starts after salt
EVP_DecryptUpdate(&ctx, clear, &len, &text[16], strlen(text)-15);
EVP_DecryptFinal(&ctx, clear, &len);
printf("%s\n", clear);
return 0;
}
http://www.ict.griffith.edu.au/anthony/info/crypto/openssl.hints
https://www.openssl.org/docs/manmaster/crypto/EVP_BytesToKey.html
https://www.openssl.org/docs/manmaster/crypto/EVP_EncryptInit.html

Resources