From the code below I am trying to get the result of the result var into a string var but no success so far.
What's wrong? Why I can't get the right result? If I print this directly it's ok...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/md5.h>
char *string = "stelios";
unsigned char s[MD5_DIGEST_LENGTH];
int main()
{
int i;
unsigned char result[MD5_DIGEST_LENGTH];
MD5(string, strlen(string), result);
// output
for(i = 0; i < MD5_DIGEST_LENGTH; i++){
sprintf(s,"%0x", result[i]);//
printf("%x",s[i]);
}
printf("\n%x",s);
return EXIT_SUCCESS;
}
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/md5.h>
char *string = "stelios";
char s[MD5_DIGEST_LENGTH * 2 + 1] = "";
int main()
{
int i;
unsigned char result[MD5_DIGEST_LENGTH];
MD5(string, strlen(string), result);
// output
for(i = 0; i < MD5_DIGEST_LENGTH; i++){
char temp[3];
sprintf(temp, "%02x", result[i]);
strcat(s, temp);
}
printf("Final Hex String: %s",s);
return EXIT_SUCCESS;
}
Each time sprintf is called, it writes the formatted value to the beginning of s, overwriting whatever was written there in the previous call. You need to do something like sprintf(s + i*2, "%02x", result[i]); (and change the length of s to 2*MD5_DIGEST_LENGTH+1).
Here's what I've used:
char *digit="0123456789abcdef";
char hex[2*MD5_DIGEST_LENGTH+1],*h;
int i;
for (h=hex,i=0; i<N; i++)
{
*h++=digit[digest[i] >> 4];
*h++=digit[digest[i] & 0x0F];
}
*h='\0';
Related
When I execute this with a normal array it's working but with a pointer it doesn't.
#include <stdio.h>
#include <string.h>
int main()
{
char source[]="Agdhefhe";
char *accum = "";
for(int i=0;i<=sizeof(*source)/sizeof(char);i++)
{
for(int j=0; j<i; j++)
strcat(accum,source);
}
printf("%s",accum);
return 0;
}
The pointer accum points to the constant initialiser which has length 1. The result of both writing to the initialiser's data area and overrunning the allocated space is undefined.
accum must point to a writable region with sufficient space allocated to accommodate the final string.
To get it right you need to allocation enough space for the destination to write to.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char source[] = "Agdhefhe";
size_t sz = 360;
char *accum = (char *) malloc(sz + 1);
*accum = '\0'; // needed for first strcat call
for (int i = 0; i <= sizeof(*source) / sizeof(char); i++)
for (int j = 0; j < i; j++)
strncat(accum, source, sz); // strncat used to not write too much
printf("%s", accum);
free(accum);
return 0;
}
This program writes Agdhefhe but can be simplified to
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char const source[] = "Agdhefhe";
size_t sz = 360;
char *accum = (char *) malloc(sz + 1);
*accum = '\0'; // needed for first strcat call
strncat(accum, source, sz);
printf("%s", accum);
free(accum);
return 0;
}
But if you wanted to duplicate the string a number of times you write:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char const source[] = "Agdhefhe";
size_t sz = 360;
char *accum = (char *) malloc(sz + 1);
*accum = '\0'; // needed for first strcat call
for (int i = 0; i <= sizeof(source) / sizeof(char); i++) // the change is here
for (int j = 0; j < i; j++)
strncat(accum, source, sz);
printf("%s", accum);
free(accum);
return 0;
}
This writes AgdhefheAgdhefheAgdhefheAgdhefhe...Agdhefhe (360 characters).
I am trying to write a program that deletes the last letter after each new line. I don't know why it isn't working but in case I set the value of i in the strncpy function with any number it works.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
int i;
char s[]="ordinateur";
char a[strlen(s)+1];
for (i=0;i<=strlen(s);i++)
{
strncpy(a,s,(10-i));
printf("%s\n",a);
}
return 0;
}
The problem is that strncpy does not NUL terminate the string when you only copy a part of the source string. So you need to handle that yourself.
One way is to add this
memset(a, 0, strlen(s)+1);
just before the strncpy
Another way is to add this
a[10-i] = '\0';
just after the strncpy
That said, please notice that you don't need strncpy inside the loop to delete the last letter. You can simply do:
int main()
{
int i;
char s[]="ordinateur";
for (i=strlen(s); i>0 ; i--)
{
printf("%s\n",s);
s[i-1] = '\0'; // Remove last char
}
return 0;
}
This compiles and works (your sample wouldn't compile on my IDE because strlen doesn't return a constant.
#include <stdio.h>
#include <stdlib.h>
#include<string>
#include <cstring>
int main()
{
int i;
char s[] = "ordinateur";
char a[11 + 1];
for (i = 0; i <= strlen(s); i++)
{
strncpy_s(a, s, (10 - i));
printf("%s\n", a);
}
return 0;
}
You are relying on VLA which AFAIK is discouraged. Instead you should use memory allocation:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
size_t i;
char s[] = "ordinateur";
char *a = calloc(strlen(s) + 1);
for (i = 0; i<= strlen(s); i++) {
strncpy(a,s, 10 - i);
printf("%s\n",a);
}
free(a);
return 0;
}
I am trying to write code where I can separate string and numbers.
The string I have to separate it completely already the numbers I have to separate every 2 numbers.
My Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void getString(const char *str) {
char nums[50];
char alphas[50];
for (int i = 0; i < strlen(str); i++) {
if (isdigit(str[i]))
strcpy(nums, str);
if (isalpha(str[i]))
strcpy(alphas, str);
}
printf("str: %s\n", alphas);
printf("num: %d\n", atoi(nums));
}
int main() {
char *str = "one01two02three03";
getString(str);
return 0;
}
What I'm trying to do should return me as follows
str: onetwothree
num1: 01
num2: 02
num3: 03
The following parses the input and produces the correct output.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int *nums = NULL;
int num_count = 0;
char save_num(int n)
{
nums = realloc(nums, sizeof(int)*(num_count+1));
nums[num_count++] = n;
return '\0';
}
void getString(const char *str)
{
char* alpha = malloc(strlen(str)+1);
char* num = malloc(strlen(str)+1);
size_t i;
alpha[0] = '\0';
num[0] = '\0';
for (i = 0; i < strlen(str); i++)
{
if (isdigit(str[i]))
strncat(num, str+i, 1);
else if(isalpha(str[i]))
{
strncat(alpha, str+i, 1);
if(strlen(num) > 0)
num[0] = save_num(atoi(num));
}
}
if(strlen(num) > 0)
save_num(atoi(num));
printf("str: %s\n", alpha);
for(i = 0 ; i < num_count ; ++i)
printf("num%Zu: %02d\n", i+1, nums[i]);
free(alpha);
free(num);
}
int main()
{
char *str = "one01two02three03";
getString(str);
return 0;
}
This provides what you have asked for:
void getString(const char *str)
{
char one[10],two[10],three[10];
int x,y,z;
char a[10],b[10],c[10];
sscanf(str,"%[^0-9]""%[0-9]""%[^0-9]""%[0-9]""%[^0-9]""%[0-9]",a,one,b,two,c,three);
x = atoi(one);
y = atoi(two);
z = atoi(three);
printf("str: %s%s%s\n",a,b,c);
printf("num: %d\n",x);
printf("num: %d\n",y);
printf("num: %d\n",z);
}
DonĀ“t forget to provide the declaration of getString before main():
void getString(const char *str);
So all together:
#include <stdio.h>
void getString(const char *str);
int main()
{
char *str = "one01two02three03";
getString(str);
return 0;
}
void getString(const char *str)
{
char one[10],two[10],three[10];
int x,y,z;
char a[10],b[10],c[10];
sscanf(str,"%[^0-9]""%[0-9]""%[^0-9]""%[0-9]""%[^0-9]""%[0-9]",a,one,b,two,c,three);
x = atoi(one);
y = atoi(two);
z = atoi(three);
printf("str: %s%s%s\n",a,b,c);
printf("num: %d\n",x);
printf("num: %d\n",y);
printf("num: %d\n",z);
}
Output:
str: onetwothree
num: 01
num: 02
num: 03
Since you have already set your strings 'nums' and 'alphas' there is no need to handle them dynamically.You should just copy the elements of the array str,one by one, to either the array num or the array alphas.
To distinguish different numbers just put a special character between numbers in the num array.
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void getString(const char *str)
{
char nums[50];
char alphas[50];
int digits = 0;
int alpha = 0;
for (int i = 0; i < strlen(str); i++) {
if (isdigit(str[i])){
while(isdigit(str[i])){
nums[digits] = str[i];
i++;
digits++;
}
nums[digits]='\n';
digits++;
}
if(isalpha(str[i])){
alphas[alpha] = str[i];
alpha++;
}
}
printf("str: %s\n", alphas);
int n,p=0;
char subbuf[5];
for(n=0;n<digits;n++){
p=n;
while(nums[n]!='\n'){
n++;
}
memcpy(subbuf,&nums[p],n-p);
printf("num: %d\n", atoi(subbuf));
}
}
int main()
{
char *str = "01two02three03";
getString(str);
return 0;
}
Be aware that strcpy sets the pointer of the first argument to point to the second argument,this means that when you write strcpy(nums,str) in your code above, you copy the entire str string to the num several times.
Using an array for this question is not necessary, unless the array is to be used later. So my answer to this question is short and simple:
#include <stdio.h>
#include <stdbool.h>
void getString(const char *str)
{
bool in_number = false;
while (*str) {
if (*str >= '0' && *str <= '9') {
if (!in_number) { // Transition from a non-digit to digit
printf(": ");
in_number = true;
}
} else if (in_number) { // Transition from a digit to non-digit
putchar('\n');
in_number = false;
}
putchar(*str++);
}
putchar('\n');
}
int main(void)
{
char *str = "one01two02three03";
getString(str);
return 0;
}
The boolean variable in_number is used to catch the transitions from a digit character to a non-digit character and from a non-digit character to a digit character.
I have a program to reverse a string and convert it to uppercase. If I write helloworld!, the output must be !DLROWOLLEH. But if I write hello world! the output is !DLRO. Could you tell me where the possible problem is?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
char * reverse(const char * text)
{
if (text==NULL)
return NULL;
int length = strlen(text);
char * reversed_string = malloc(length+1);
for(int i = 0; i < length/2; ++i)
{
reversed_string[i] = text[(length-1) - i];
reversed_string[(length-1) - i] = text[i];
}
reversed_string[length] = '\0';
//upper(reversed_string);
return reversed_string;
}
void upper(char *str1)
{
while(*str1!='\0')
{
if(*str1>96&&*str1<123)
*str1=*str1-32;
str1++;
}
}
int main(int argc, char * argv[])
{
char p[256];
fgets(p, sizeof(p), stdin);
char * rev_str = reverse(p);
upper(rev_str);
printf("%s\n", rev_str);
rev_str = 0;
return 0;
}
The problem is here
for(int i = 0; i < length/2; ++i)
It length is an odd number (like 11 in your example), this will implicitly round down, and as a consequence, you never write to the middle element in the string. Un your case, this happened to be 0, but that is not guaranteed to be so, so any character might have appeared there, instead of terminating the string early.
The easiest fix would be changing that to (length+1)/2, but that will have the effect that you write the middle element twice.
Actually, I think it is much easier if you just reverse the string just by iterating over it in one direction instead of from both.
I've modified your code and it works as expected.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
char * reverse(const char * text)
{
if (text==NULL)
return NULL;
unsigned long length = strlen(text);
char * reversed_string = malloc(length+1);
for(int i = 0; i < length; ++i)
{
reversed_string[i] = text[(length-1) - i];
//reversed_string[(length-1) - i] = text[i];
}
reversed_string[length] = '\0';
//upper(reversed_string);
return reversed_string;
}
void upper(char *str1)
{
while(*str1!='\0')
{
if(*str1>96&&*str1<123)
*str1=*str1-32;
str1++;
}
}
int main(int argc, char * argv[])
{
char p[256];
fgets(p, sizeof(p), stdin);
char * rev_str = reverse(p);
printf("%s\n", rev_str);
upper(rev_str);
printf("%s\n", rev_str);
rev_str = 0;
return 0;
}
I want codes for randomly selects the word (meaningful or meaningless) from 26 letters. The word contain 6 letters. I have the codes for C program or objective C, or you will give any idea to me.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
main()
{
srand(time(NULL));
for (int i = 0; i < 6; ++i)
{
putchar('a' + (rand() % 26));
}
putchar('\n');
return EXIT_SUCCESS;
}
Salt to taste.
Update0
It would seem the OP does not know how to compile the above. If saved into a file called so.c, compile it with make so CFLAGS=-std=c99 from the same folder.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* Written by kaizer.se */
void randword(char *buf, size_t len)
{
char alphabet[] = "abcdefghijklmnopqrstuvxyz";
size_t i;
for (i = 0; i < len; i++) {
size_t idx = ((float)rand()/RAND_MAX) * (sizeof(alphabet) -1);
buf[i] = alphabet[idx];
}
buf[len] = '\0';
}
int main(void) {
char buf[1024];
srand(time(NULL));
randword(buf, 7);
printf("Word: %s\n", buf);
return 0;
}
Test:
$ ./rword
Word: xoilfvv