Here is a snippet of my code:
#include <stdio.h>
#include "uhash.h"
#include <openssl/evp.h>
char * hash(item a)
{
const char * str= a.k;
int len= strlen(str);
int md_len;
unsigned char md_value[EVP_MAX_MD_SIZE]; /* Buff to store change result */
EVP_MD_CTX *mdctx; /* Digest data structure declaration */
const EVP_MD *md;
OpenSSL_add_all_digests();
md = EVP_get_digestbyname("SHA256");
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, str, len);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_destroy(mdctx);
char md5str[33];
for(int i=0;i<md_len;++i)
{
sprintf(&md5str[i*2],"%02x",(unsigned int)md_value[i]);
}
printf("%s\n", md5str);
return md5str;
}
int main(int argv, char **argc)
{
char *c;
if (argv>0)
{
int i=0;
int s=0;
for(i=1;i<argv;i++)
{
s+=strlen(argc[i]);
}
c=(char *)(malloc(sizeof(char)*s*(argv-2)+1));
s=0;
for(i=1;i<argv;i++)
{
char *t=c+s;
memcpy(t,argc[i],strlen(argc[i]));
if(i!=argv-1){
printf("%d\n", argv);
t[strlen(argc[i])]=' ';
s++;
}
s+=strlen(argc[i]);
}
*(c+s)='\0';
}
printf("%s\n", c);
item * kee= malloc(sizeof(item));
kee->k=c;
kee->v=10;
char *res= hash(*kee);
fflush(stdout);
if(res==NULL)
printf("result is null...");
else
printf("%s\n",res);
fflush(stdout);
}
So the main function takes the arguments fine(tested) and passes it fine(tested) but the hash() function although computing the hash, does not either return the right value or I can't print the result in main. I've been trying to check for errors since yesterday but I'm not very smart so any help would be greatly appreciated!
Root cause: You are returning something that has been created on the stack and once it returns it is wiped. res is pointing into your stack.
Fix: Put the declaration of md5str outside the routine hash or make it static within the routine hash.
Related
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stats.h"
/* Size of the Data Set */
#define SIZE (40)
void print_array (unsigned char *p, int l) {
int i;
for (i=0;i<l;i++) {
printf("%d\t",*p);
p++;
}
}
void print_array_int (int *p, int l) {
int i;
for (i=0;i<l;i++) {
printf("%d\t",*p);
p++;
}
}
void typecasting(unsigned char test[SIZE], int array[SIZE]) {
int i=0;
unsigned char *token = strtok(test,",");
while (token) {
if(i<SIZE) {
array[i++] = atoi(token);
}
token = strtok(NULL,",");
}
}
void main() {
int array[SIZE] = {};
unsigned char test[SIZE] = {34,201,190,154,8,194,2,6,114,88,45,76,123,87,25,23,200,122,150,90,92,87,177,244,201,6,12,60,8,2,5,67,7,87,250,230,99,3,100,90};
/* Other Variable Declarations Go Here */
/* Statistics and Printing Functions Go Here */
print_array(test, SIZE);
typecasting(test,array);
print_array_int(array,SIZE);
}
What I want in this code is to convert the array of char into an array of int.
Previously I tried doing this by using pointers but didn't work and it showed stack smashing error. I want to convert this array of char into array of int to perform some mathematical operations.
You are trying too hard. Here's how typecasting should look
void typecasting(unsigned char test[SIZE], int array[SIZE]) {
for (int i = 0; i < SIZE; ++i)
array[i] = test[i];
}
Your code might be suitable if you were converting from a C string, i.e. if your original test array was
char test[] = "34,201,190,154,8,194,2,6,114,88,45,76,123,87,25,23,...";
So I guess you could say you're misunderstanding the nature of char (and unsigned char) in C++. They can represent character data as in char greeting[] = "hello"; or they can represent small integers as in char test[] = {1,2,3};.
i wrote some code that is supposed to find the location of a given string in an array of strings.
problem is- it doesn't give the location. it gives something else.
i understand that probably the problem has to do with the differences between the pointers that are involved- a previous version that dealt with finding the position of a letter in a word worked well.
after a lot of attempts to figure out where is the bug, i ask your help.
kindly, explain me what should be done.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int what (char * token);
main()
{
int i=0;
char string[]="jsr";
char *token;
token=&string[0];
i=what(token);
printf(" location of input is %d \n", i);
return 0;
}
int what (char * token)
{
int i=1;
char *typtbl[]={"mov",
"cmp",
"add",
"sub",
"not",
"clr",
"lea",
};
char * ptr;
ptr=(char *)typtbl;
while (!(strcmp(ptr,token)==0))
{
ptr=(char *)(typtbl+i);
i++;
}
return i;
}
As pointed out, you did not design function what properly. What value should it return if your search function go through all the pointers but does not find the desired string? Typically in that case return -1 would be a choice to indicate nothing found. Also in this case, using a for loop would probably be more suitable, you can just return the index immediately instead of going through all pointers.
int what(char *token)
{
char *typtbl[] = {
"mov",
"cmp",
"add",
"sub",
"not",
"clr",
"lea",
};
for( size_t i = 0; i < sizeof(typtbl)/sizeof(char*); ++i )
{
char *ptr = typtbl[i];
if(strcmp(ptr, token) == 0)
{
return i; // found something
}
}
return -1; // found nothing
}
A cleaner working version.
Main issue is in the (char *)(typtbl+i) replaced by typtbl[i] in the following code. typtbl+i is equivalent to &typtbl[i], so if my memory is good, it's a pointer on the pointer of the string and not the pointer of string itself
I added a NULL at the end of the array to be able to stop if the string is not present and return -1 to clearly say it was not found.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int what(char *token);
int main()
{
int i = 0;
char string[] = "jsr";
i = what(string);
printf(" location of input is %d \n", i);
return 0;
}
int what(char *token)
{
char *typtbl[] = {
"mov",
"cmp",
"add",
"jsr",
"not",
"clr",
"lea",
NULL
};
int i = 0;
while(typtbl[i] && !(strcmp(typtbl[i], token) == 0)) {
++i;
}
if(!typtbl[i])
i = -1;
return i;
}
char *token; token=&string[0]; was useless because string == &string[0].
A few things:
Your main function is missing its return type.
The while loop in what doesn't stop when the element isn't found. Therefore you are reading out of bounds.
This should do the work w/o pointer arithmetic.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int what (char * token);
int main(){
int i=0;
char string[]="jsr";
char *token;
token=&string[0];
i=what(token);
printf(" location of input is %d \n", i);
return 0;
}
int what (char * token){
unsigned int i=0;
char *typtbl[]={"mov",
"cmp",
"add",
"sub",
"not",
"clr",
"lea",
};
unsigned int typtbl_x_size = sizeof(typtbl)/sizeof(typtbl[0]);
char * ptr;
ptr=typtbl[i];
while (!(strcmp(ptr,token)==0)){
i += 1;
if (i >= typtbl_x_size){
printf("element not in list\n");
return -1;
}
ptr=typtbl[i];
}
return i;
}
I got this part of a C program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void){
char *mRNA = spleissen("AUAGUAAAAGCUCUGUUUAGGAGA", "GU", "AG");
printf("mRNA: %s\n", mRNA);
free(mRNA);
return 0;
}
I have to write the function spleissen which should work like this: it cuts out a string which goes from a GU to an AG and everything in between those two. So the program output is:
mRNA: AUACUCUGAGA
I don't really know how I can cut those parts out.
I am not allowed to use includes other than stdio, string and stdlib.
char *spleissen(const char *src, const char *start, const char *end){
size_t len = strlen(src);
char *s, *e, *ret, *work;
ret = work = malloc(len + 1);
strcpy(work, src);
len = strlen(end);
while(s = strstr(work, start)){
if((e = strstr(s, end))==NULL)
break;//delete upto last?
memmove(s, e + len, strlen(e+len)+1);
work = s;
}
return ret;
}
I think you can simply do this:
char *spleissen(char *array, char *G, char *A)
{
int l=strlen(array);
int i, j=0;
char returnstr[10010];
int b=0;
for(i=0; i<l; i++)
{
if(G[0]==array[i] && G[1]==array[i+1])
{
b=1, i++;
continue;
}
else if(A[0]==array[i] && A[1]==array[i+1] && b==1)
{
b=0, i++;
continue;
}
if(b==0)
{
returnstr[j]=array[i];
j++;
}
}
return returnstr;
}
i'm try to get a bowfish function working for simple char buffers. The program fails when I try to decrypt an encrypted buffer and fails on the EVP_CipherFinal_ex() call.
#include <string.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <openssl/blowfish.h>
#include <openssl/evp.h>
int do_crypt(unsigned char *inbuf, int inlen, unsigned char *outbuf, int *outlen, int do_encrypt) {
outbuf=(unsigned char*) malloc(inlen+EVP_MAX_BLOCK_LENGTH);
int tmplen=0;
unsigned char key[] = "0123456789";
unsigned char iv[] = "12345678";
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_bf_cbc(), NULL, NULL, NULL, do_encrypt);
EVP_CIPHER_CTX_set_key_length(&ctx, 10);
EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
if(!EVP_CipherUpdate(&ctx, outbuf, outlen, inbuf, inlen)) {
/* Error */
printf("* update failed *\n");
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
int db=*outlen;
if(!EVP_CipherFinal_ex(&ctx, outbuf+db, &tmplen)) {
/* Error */
ERR_print_errors_fp(stderr);
printf("* finalise failed *\n");
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
(*outlen)=db+tmplen;
EVP_CIPHER_CTX_cleanup(&ctx);
return 1;
}
int main(int argc, char **argv) {
char *plain="ENCRYPT DECRYPT this string";
int plain_len=strlen(plain);
unsigned char *cipher;
int cipher_len;
printf("***** ENCRYPT *****\n");
if (!do_crypt((unsigned char*) plain, strlen(plain), cipher, &cipher_len, 1)) {
printf("failed to encrypt\n");
return 1;
}
char *decrypt;
int decrypt_len;
printf("***** DECRYPT *****\n");
if(!do_crypt( cipher ,cipher_len , decrypt, &decrypt_len, 0)) {
printf("failed to decrypt\n");
return 1;
}
printf("decrypt=\"%s\"\n",decrypt);
printf("decrypt_len=%d\n",decrypt_len);
return 0;
}
any help would be much appreciated.
You have two problems: The first is that you should not cast the result of malloc in C. This is the most likely reason EVP_CipherUpdate crashes.
The second error is that arguments in C are passed by value, meaning they are copied and the functions only have copies of the arguments passed by the caller. This means that in the do_crypt function when you assign to the argument output you are only assigning to the local copy inside the function, the variable cipher in the main function will not be changed.
The last problem can be solved by imitating pass by reference by passing a pointer to the pointer, and use the address-of operator & and the dereference * operator:
/* Note extra indirection */
/* | */
/* v */
int do_crypt(unsigned char *inbuf, int inlen, unsigned char **outbuf, int *outlen, int do_encrypt) {
...
*output = malloc(...);
...
if(!EVP_CipherUpdate(&ctx, *outbuf, outlen, inbuf, inlen)) { ... }
...
}
You then call it like
do_crypt((unsigned char*) plain, strlen(plain), &cipher, &cipher_len, 1)
Im making an application that uses of API-threads in C, The program takes N-files (N>2) with names disordered,per each file is generated a thread of execution which sort the files using the function qsort, after being ordered files, each thread should create a file keeping the original file intact and displaying the sorted file to another file with the extension <.sorted>. The program sorts the numbers without problems, even if I put standard output displays the result on screen, but when I try to create the output file with extension .sorted the program breaks out.
this is my code file.c
#include <stdio.h> /* Standard buffered input/output */
#include <stdlib.h> /* Standard library functions */
#include <string.h> /* String operations */
#include <pthread.h> /* Thread related functions */
#include "pf1.h" /* Header specific to this app */
pthread_attr_t attr;
void *thread_worker(void *name_file)
{
FILE *entrada, *salida;
char* nombres = (char*)name_file;
int numero;
char temp [10000];
int i;
stats_t estadisticas;
printf ("File_name:%s\n", nombres);
entrada = fopen(nombres, "r");
salida = fopen (strcat(nombres, ".sorted"), "w");
while (!feof(entrada)){
fscanf (entrada, "%s\n",temp);
numero++;
}
char* lista[numero]; //array to sort the file
rewind (entrada);
for (i=0;i<numero;i++)
{
fscanf(entrada," %[^\n]", temp);
lista[i] = (char*)malloc((strlen(temp)+1)*sizeof(char));
strcpy(lista[i], temp);
}
size_t large = sizeof(lista) / sizeof(char *);
qsort(lista,large ,sizeof(char *) ,cstring_cmp );
printf ("Archivo Ordenado\n", i+1);
for (i=0;i<large;i++)
printf("%s\n",lista[i]);
pthread_exit(NULL);
}
int main(int argc, char *argv [])
{
stats_t **stats;
int i, rc;
pthread_t my_threads[argc-1];
pthread_attr_init(&attr);
if (argc <3) {
printf ("|files| > 2\n");
}else{
printf("files to sorted: %d\n", argc - 1);
for (i = 1; i < argc; i++){
//printf("%s%s\n", argv[i], (i < argc-1) ? " " : "");
rc = pthread_create(&my_threads[i], &attr, thread_worker, (void *)argv[i]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n",rc);
return -1;
}
}
}
return 0;
} /*end main */
this is mi file.h
#ifndef PF1_H_
#define PF1_H_
typedef struct _stats_t
{
char *longest, *shortest;
unsigned int numlines;
} stats_t;
int cstring_cmp(const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return -strcasecmp(*ia, *ib);
/* strcmp functions works exactly as expected from
comparison function */
}
void print_cstring_array(char **array, size_t len)
{
size_t i;
for(i=0; i<len; i++)
printf("%s | ", array[i]);
putchar('\n');
}
#endif /* PF1_1_H_ */
I would like some help with this problem because I can not see which is the fault ... thanks to all in advance and excuse my English
This line here may be your problem:
salida = fopen (strcat(nombres, ".sorted"), "w");
From what I can tell, that nombres variable is coming from argv. Since you're not the one allocating memory for argv, you don't know that there will be extra space for the ".sorted" (and there probably won't be). If you strcpy it to your own buffer with space for the ".sorted", you should be fine.
#define EXT_LEN 7
#define MAX_TOTAL_LEN 250
#define MAX_FILE_LEN 242 //MAX_TOTAL_LEN - EXT_LEN - 1
char *name_ptr;
char nombres[MAX_TOTAL_LEN];
int len;
name_ptr = (char*)name_file;
len = strlen(name_ptr);
if (len > MAX_FILE_LEN) {
len = MAX_FILE_LEN;
}
strncpy(nombres, name_ptr, len);
strcpy(nombres+len, ".sorted");
salida = fopen (nombres, "w");
I once had issues about not passing an int identifier while calling thread execution functions. Try building a struct with both an integer identifier and the filename, then pass it as a parameter to your thread_worker() function.