#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void initRandom() {
srand(time(NULL));
}
int intUniformRnd(int a, int b){
return a + rand() % (b-a+1);
}
const char* animaisQuatro[] = {"gato", "urso","vaca"};
int main() {
char quatro[4] = {'*' , '*' , '*', '*'};
initRandom();
printf("%s\n", animaisQuatro[intUniformRnd(0,2)]);
for(int i=0;i<4;i++){
printf("%c", quatro[i]);
}
return 0;
}
I have this code that give me a random animal from the array const char* animaisQuatro[] = {"gato", "urso","vaca","lapa"}; from here
initRandom();
printf("%s\n", animaisQuatro[intUniformRnd(0,2)]);
and then I want to put that random animal in another array letter by letter but I don't know how
First I reduced your code to a minimal and reproducible example (something you should do whenever you ask a question):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void initRandom() {
srand(time(NULL));
}
int intUniformRnd(int a, int b){
return a + rand() % (b-a+1);
}
const char* animaisQuatro[] = {"gato", "urso","vaca"};
int main() {
char quatro[4] = {'*' , '*' , '*', '*'};
initRandom();
printf("%s\n", animaisQuatro[intUniformRnd(0,2)]);
for(int i=0;i<4;i++){
printf("%c", quatro[i]);
}
return 0;
}
Then you can proceed like this:
int main() {
char quatro[4] = {'*' , '*' , '*', '*'};
initRandom();
// Get the animal name from a random position
char* name = animaisQuatro[intUniformRnd(0, 2)];
// Iterate four times
for (int i = 0; i < 4; i++) {
// Assign each `name` index to its respective `quatro` position
quatro[i] = name[i];
}
printf("%s", quatro);
return 0;
}
Tip: you can avoiding hardcoding the 2 when calling intUniformRnd. Note that
printf("%d\n", (int) sizeof(animaisQuatro));
printf("%d\n", (int) sizeof(char*));
printf("%d\n", (int) sizeof(animaisQuatro) / sizeof(char*));
outputs
24
8
3
Therefore, you can do
int length = (int) sizeof(animaisQuatro) / sizeof(char*);
int pos = intUniformRnd(0, length - 1);
This way, if you want to add more elements to animaisQuatro, you don't need to change the value inside intUniformRnd.
I want to put that random animal in other array letter by letter
To copy a string to another character array, code could use
// Risky
strcpy(quatro, animaisQuatro[intUniformRnd(0,2)]);
That would overflow quatro[] if it is too small and leads to undefined behavior. (Bad)
A better way to copy and prevent buffer overflow and alert of a failure:
int len = snprintf(quatro, sizeof quatro, "%s", animaisQuatro[intUniformRnd(0,2)]);
if (len >= sizeof quatro) {
fprintf(stderr, "quatro too small.\n");
}
Since C99 and selectively afterword, code could use a variable length array to form a right-size quatro array.
const char *animal = animaisQuatro[intUniformRnd(0,2)];
size_t sz = strlen(animal) + 1;
char quatro[sz];
strcpy(quatro, animal);
Yet since intUniformRnd[] is constant, no need to copy the text, just copy the address to a pointer:
const char *quatro = animaisQuatro[intUniformRnd(0,2)];
Related
I did a simple program that splits a string in substrings, using the whitespace as a split reference. The program was working as expected, so I've decided to put this code inside a function that is called "substring_whitespace".This function return a size_t value which is the number of substring's. The function arguments are char* buffer[] and char* string. Both are pointers, the first will store the substring's, and the second is the string that'll be splited.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
size_t substring_whitespace(char* buffer[],char* string) {
size_t initial_string_size = strlen(string) + 1;
char actual_string[initial_string_size];
char strings[initial_string_size][initial_string_size];
strcpy(actual_string,string);
size_t c = 0;
for(; c<initial_string_size; c++) {
size_t first_whitespace_index = strcspn(actual_string," ");
char substring[first_whitespace_index];
for(size_t d = 0; d<=first_whitespace_index; d++) {
if(d == first_whitespace_index)
substring[first_whitespace_index] = 0;
else
substring[d] = actual_string[d];
}
size_t actual_string_length = strlen(actual_string);
size_t new_actual_string_length = (actual_string_length - first_whitespace_index) + 1;
char new_actual_string[new_actual_string_length];
for(size_t d = 0,i = first_whitespace_index + 1; i<=actual_string_length + 1; i++,d++) {
if(i == actual_string_length)
new_actual_string[d] = 0;
else
new_actual_string[d] = actual_string[i];
}
strcpy(actual_string,new_actual_string);
strcpy(strings[c],substring);
buffer[c] = strings[c];
if(new_actual_string_length == 1)
break;
}
return ++c;\
}
int main() {
char string[1000];
fgets(string,sizeof(string)/sizeof(string[0]),stdin);
string[strcspn(string,"\n")] = 0;
char* buffer[strlen(string) + 1];
size_t buffer_length = substring_whitespace(buffer,string);
for(int d = 0; d<buffer_length; d++) {
printf("\n%s",buffer[d]);
}
}
After I test, the results were not as expected, so during my debug I detect that the char were being changed after get off the function by pointer. This behavior is only detectable if I try to print the buffer strings in the main.
strings is a local variable whose lifetime ends when the function returns. The easiest fix is to copy the string when assigning a value buffer[c]:
buffer[c] = strdup(strings[c]);
Another option is to change the design and return an array of ranges relative to your input string. For example struct range { char *s; size_t len; };, and if string is "hello world" the function could return [{string, 5}, {string+6, 5}].
The function char *my(char *s, int n) takes a string s and shifts the characters of s by n places, causing the characters to wrap around the string.
For example, given the string "This is my Apple!" , a shift of n = 2 will result in
String1: "Th"
String2: "is is my Apple!"
if n<0 it will shift in negative direction.
You can just use printf to split a string. If you want the result in a char *, you have to allocate some memory and use sprintf instead.
Here is a example using sprintfand memory allocation to return a char *.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *shift(char *string, int n)
{
int len = strlen(string);
char *shiftedString = malloc(len + 1);
n %= len; // in case you shift over string length
if (n < 0) n += len; // backward shift
sprintf(shiftedString, "%s%*.*s", string + n, n, n, string);
return shiftedString;
}
int main()
{
char *result = shift("This is my Apple!", 2);
printf("shifted string : %s\n", result);
free(result);
return 0;
}
the string is actually a char-array char[]
you could use the strlen function in combination with a for loop like so.
You can put that in a function thus creating your own function that would shift letters based on input N.
#include <stdio.h>
#include <string.h>
int main()
{
char string[] = "This is my Apple!";
//Initialize "n" before initializing the string variables.
int n = 2;
int len = strlen(string);
char string1[n];
char string2[len - n];
for(int i = 0;i<len;i++){
if(i<n){
string1[i]=string[i];
}else{
string2[i-n]=string[i];
}
}
printf("string = %s\n",string);
printf("string1 = %s\n",string1);
printf("string2 = %s\n",string2);
return 0;
}
I have for example a string (mathematical equation in postfix notation) that looks like this: The numbers are 5.33,5.32,6.33,3.22
5.335.32*6.333.22++
I'm looking to make it into prefix notation but simply reversing the string won't work due to the fact it has to retain the value of the number.
I've thought of doing a normal character by character swap in a for loop, and when encountering a digit make that into a substring and place it on afterwards but I haven't gotten it to work properly and now I'm stuck.
My end-goal is to make a binary expression tree out of that, so if there's an easier way than doing this also please let me know.
A stack-based approach:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *postfix_to_prefix(const char *string) {
char operator, *stack[1024];
int s = 0, number, fraction;
const char *tokens = string;
while (1) {
if (sscanf(tokens, "%1d.%2d", &number, &fraction) == 2) {
stack[s] = malloc(sizeof("1.00"));
(void) sprintf(stack[s++], "%4.2f", number + (fraction / 100.0));
tokens += strlen("1.00");
} else if (sscanf(tokens, "%c", &operator) == 1) {
char *operand1 = stack[--s];
char *operand2 = stack[--s];
stack[s] = malloc(strlen(operand1) + strlen(operand1) + sizeof(operator) + sizeof('\0'));
(void) sprintf(stack[s++], "%c%s%s", operator, operand1, operand2);
free(operand1);
free(operand2);
tokens += sizeof(operator);
} else {
break;
}
}
return stack[--s];
}
int main() {
const char *string = "5.335.32*6.333.22++";
printf("%s\n", string);
char *inverted = postfix_to_prefix(string);
printf("%s\n", inverted);
free(inverted);
return 0;
}
OUTPUT
> ./a.out
5.335.32*6.333.22++
++3.226.33*5.325.33
>
This is a bare bones implementation with no real error checking nor other finishing touches. You'll want to check that non-communitive operations like subtraction and division come out with the operands in the correct order and reverse them if not.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char exp[] = "5.335.32*6.333.22++";
size_t len = strlen(exp);
char temp[len];
char *p = temp;
for(int i = len-1; i >= 0; ){
if(isdigit(exp[i])){
memcpy(p, &exp[i-4+1], 4);//all number have a length of 4
p += 4;
i -= 4;
} else {
*p++ = exp[i--];//length of op is 1
}
}
memcpy(exp, temp, len);//Write back
puts(exp);//++3.226.33*5.325.33
return 0;
}
I have the task to make a little program with pointers and I am facing a problem with const char*s. The program is meant to count the number of times that a sub-string appears in a main-string. Also, the different positions, where the sub-strings start, should be saved in a char** ptr. This is my little testing code:
#include <stdio.h>
#include <string.h>
main()
{
int i=-1;
int k=0;
char** ptr;
char* str="cucumber";
char* substr="cu";
while(strstr(str, substr)!=NULL)
{
i++;
ptr[i]=strstr(str, substr);
str = strpbrk(str, substr)+1;
k++;
}
printf("%i",k);
}
It should print 2, since the sub-string 'cu' appears 2 times in 'cucumber' - yet, my compiler tells me that I am using chars, when I should use constant ones. Except, I don't know how to do that.
The strstr() function requires them. What should I change?
// note:
// 1) correction to declaration of main()
// 2) addition of return statement
// 3) 'substr' is a poor name choice for a variable, as
// a) it looks like a C lib function (it is a ACL library function)
// b) it does not clearly convey what the variable contains
// 4) clutter in the 'while' loop removed
// 5) 'while' loop is replaced by a 'for' loop so more can be accomplished with less code
// 6) unneeded variables are eliminated
// 7) the 'for' loop stops when there is no possibility of further testStr occurrences
// 8) the printf() clearly indicates what is being printed
#include <stdio.h>
#include <string.h>
int main()
{
char* testStr="cucumber";
char* findStr="cu";
int k = 0;
for( int i=0; strlen(&testStr[i]) >= strlen(findStr); i++)
{
if( strstr(&testStr[i], findStr) != NULL)
{
k++;
}
}
printf("\nnumber of occurrences of %s in %s is %d\n", findStr, testStr, k);
return(0);
}
Allocate memory for storing the pointer values
#include <stdio.h>
#include <string.h>
#define MAX_SUB_STR 10
int main()
{
int i;
int k;
char* ptr[MAX_SUB_STR];
char* str="cucumber";
char* temp;
char* substr="cu";
i = 0;
k = 0;
temp = str;
while(strstr(temp, substr)!=NULL && k < MAX_SUB_STR)
{
ptr[k]=strstr(temp, substr);
temp = ptr[k] + strlen(substr);
k++;
}
printf("%i\n",k);
for (i = 0; i < k; i++)
printf("%p\n",ptr[i]);
return 0;
}
I am using sprintf for string formation in C.
I need to insert '+' and '-' sign before float value.
This positive and negative signs are inserted by checking a flag after that i insert the float value.
Now i want to make this whole number in right alignment along with positive or negative sign.
Currently this is my formatted string:
+300.00
-200.00
+34.60
I want output like following,
+300.00
+233.45
-20.34
I have written following code:
char printbuff[1000], flag = 1;
double temp=23.34, temp1= 340.45;
sprintf(printBuff, "%c%-lf\n%c%-lf",
(Flag == 1) ? '+' : '-',
temp,
(Flag == 1) ? '+' :'-',
temp1);
I am getting following output:
+23.34
+340.45
Instead of the desired:
+23.45
+340.45
How can I do this?
use like this
sprintf(outputstr, "%+7.2f", double_number);
E.g.
#include <stdio.h>
#include <string.h>
#include <math.h>
void output_string(char output_buffer[], double nums[], size_t size){
/* use '+' flag version
int i,len=0;
for(i=0;i<size;++i)
len += sprintf(output_buffer + len, "%+7.2f\n", nums[i]);
*/ //handmade version
int i, len=0;
for(i=0;i<size;++i){
char sign = nums[i] < 0 ? '-' : '+';
char *signp;
double temp = abs(nums[i]);
len += sprintf(signp = output_buffer + len, "%7.2f\n", temp);
signp[strcspn(signp, "0123456789")-1] = sign;//The width including the sign is secured
}
}
int main(){
double nums[] = {
+300.00,
-200.00,
+34.60,
+300.00,
+233.45,
-20.34
};
char output_buffer[1024];
int size = sizeof(nums)/sizeof(*nums);
output_string(output_buffer, nums, size);
printf("%s", output_buffer);
return 0;
}
int main()
{
char s[100];
double x=-100.00;
sprintf(s,"%s%f",x<0?"":"+",x);
printf("\n%s",s);
x = 1000.01;
sprintf(s,"%s%f",x<0?"":"+",x);
printf("\n%s",s);
return 0;
}
Here is the code.
Its O/p is ::
-100.000000
+1000.010000
you need a separate buffer, in which you sprintf your number with your sign, and that resulting string you can sprintf into the rightjustified resultbuffer.
You need something like:
char str[1000];
double v = 3.1415926;
sprintf(str, "%+6.2f", v);
The + indicates "show sign".
A more complete bit of code:
#include <stdio.h>
int main()
{
double a[] = { 0, 3.1415, 333.7, -312.2, 87.8712121, -1000.0 };
int i;
for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
{
printf("%+8.2f\n", a[i]);
}
return 0;
}
Output:
+0.00
+3.14
+333.70
-312.20
+87.87
-1000.00
Obviously, using sprintf, there would be a buffer involved, but I believe this shows the solution more easily.