I have a problem generating a random string in a function.
In the code below I have used ASCII characters from 65 to 90. I want to include 48 to 57, skipping 58 to 64.
Is there any way to do this?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
int main()
{
char s[30];
random_string(s, 6,65,90);
printf("\n%s\n", s);
return 0;
}
void random_string(char * string, unsigned length,int min,int max)
{
/* Seed number for rand() */
srand((unsigned int) time(0) + getpid());
/* ASCII characters 33 to 126 */
unsigned int num_chars = length - 1;
unsigned int i;
for (i = 0; i < num_chars; ++i)
{
string[i] = rand() % (max - min + 1) + min;
}
string[num_chars] = '\0';
}
How about this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char* wanted = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
void random_string(char* target, unsigned len, const char* sample, unsigned slen) {
while(len) {
*target = sample[rand() % slen];
++target, --len;
}
*target = '\0';
}
int main() {
char rnd_str[21];
//srand(...)
random_string(rnd_str, 20, wanted, strlen(wanted));
printf("%s\n", rnd_str);
}
I think that simplest way to achieve that is to reroll rand() if you have got number in unwanted range. To specify desired range, you can use bitmask or bool array instead of min/max.
It will look something like this:
do { c = rand() % 256; } while (!desired[c]);
string[i] = c;
Related
In this code you "randomly" fill your array with letters and if it hits the word you are looking for returns the amount of trys to get it correct. What I want to implement is a way of checking if it is spelled correct from the first character going onwards. Any ideas?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int main() {
char *search= "SOMETHING";
int clk = clock();
printf ("clk=%d\n",clk);
srand(clk);
int len = strlen(search);
char *tafel = (char *) malloc (len+1);
tafel[len] = 0;
int pos;
char letter;
long i=0;
char check;
while (strcmp (search,tafel) != 0 ) {
i++;
letter = rand() % 26 +'A';
pos = rand() % len;
//pos=(pos+1)%len;
tafel[pos] = letter;
if (i%10000000==0) {
printf("%4ld mio: %s\n", i / 1000000, tafel);
printf ("%d\n",strcmp (search,tafel));
}
}
printf("It takes %ld trys to find '%s'\n",i,tafel);
printf ("%d\n",strcmp (suchwort,tafel));
return 0;
}
I have a 3 digit integer myInt:
int myInt = 809;
I need an output string *myStr which consists of the 2 last digits. Therefore
char *mystr = "09";
What would be the easiest solution to do that?
You can do like this:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buf[32];
int myInt = 809;
char* mystr;
snprintf(buf, sizeof buf, "%d", myInt);
if (strlen(buf) > 2)
mystr = buf + strlen(buf) - 2;
else
mystr = buf;
fputs(mystr, stdout);
return 0;
}
Here is a simple solution:
#include <stdio.h>
int main(void) {
char buf[3];
char *myStr;
unsigned int myInt = 809;
buf[0] = myInt / 10 % 10 + '0'; /* tens digit */
buf[1] = myInt % 10 + '0'; /* unit digit */
buf[2] = '\0'; /* null terminator */
myStr = buf;
puts(mystr);
return 0;
}
For the specific case of turning "magic numbers" into strings, you can as well do that at compile-time. That is, when you have an integer constant rather than a run-time value:
#include <stdio.h>
#define VAL 809
#define STRINGIFY(x) #x
#define STR(i) STRINGIFY(i)
#define SUBSTR(i, n) &(STRINGIFY(i))[n]
int main (void)
{
int whatever = VAL;
puts(STR(VAL));
puts(SUBSTR(VAL, 1));
return 0;
}
Output:
809
09
No pointer magic necessary here. Just use plain math (the remainder operator: %), along with some suitable formatting:
#include <stdio.h>
int main(void)
{
char a[3]; /* 2 characters for any value >= 0 and < 100. So we rely on the 100 below.
+1 character for the `0`-terminator to make this a C-string*/
int i = 809;
assert(i >= 0);
sprintf(a, "%02d", i % 100);
puts(a);
}
or avoiding magic numbers:
#include <stdio.h>
long long power_integer(int base, int x)
{
if (0 == x)
{
return 1;
}
return base * power_integer(x - 1);
}
#define CUTOFF_BASE (10)
#define CUTOFF_DIGITS (2)
int main(void)
{
char a[3];
char f[8]; /* To hold "%01lld" to "%019lld".
(A 64 bit integer in decimal uses max 19 digits) */
int i = 809;
assert(i >= 0);
sprintf(f, "%%0%dlld*, CUTOFF_DIGITS);
sprintf(a, f, i % power_integer(CUTOFF_BASE, CUTOFF_DIGITS));
puts(a);
}
Output would be:
09
You could try something like this:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv){
int myInt = 809;
char buf[16]; // buffer big enough to hold the string representation
sprintf(buf, "%d", myInt); // write the string to the buffer
char* myStr = &buf[strlen(buf) - 2]; // set a pointer to the second last position
printf("myStr is %s\n", myStr);
return 0;
}
I am trying to convert an signed integer array to character pointer. I wrote a sample programe like below.
Expected output be "10-26357-35"
Please help me.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int16_t frame_i[5] = {10, -26, 35, 7, -35};
size_t i;
char *s = malloc(5*2+1);
for(i = 0; i<5; i++) {
snprintf(s + i * 2, 3, "%hd", frame_i[i]);
}
return 0;
}
You have to take the sign into account. In other words - you can't just assume all numbers to be 2 chars width.
Try something like:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int16_t frame_i[5] = {10, -26, 35, 7, -35};
size_t i;
char *s = malloc(5*3+1); // Allocate memory to hold 3 chars for each number
char *tmp = s; // Add a tmp pointer to know how far you are
for(i = 0; i<5; i++) {
if (frame_i[i] >= 0) // Check the sign
{
snprintf(tmp, 3, "%02hd", frame_i[i]); // Requires 2 chars
tmp += 2;
}
else
{
snprintf(tmp, 4, "%03hd", frame_i[i]); // Requires 3 chars
tmp += 3;
}
}
// Print the result
printf("%s\n", s);
// Release memory
free(s);
return 0;
}
Notice that the solution only works for numbers in the range -99 to 99 and that it will put a 0 in front of number in the range -9 to 9.
A more general (and simpler) solution which handles a wider range and doesn't add 0 in front can be obtained by utilizing that snprintf returns the number of characters printed. Something like:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_SIZE 1000
int main(void) {
int16_t frame_i[5] = {10, -26, 35, 7, -35};
size_t i;
int size_available = MAX_STRING_SIZE;
int cnt;
char *s = malloc(MAX_STRING_SIZE);
char *tmp = s;
for(i = 0; i<5; i++) {
cnt = snprintf(tmp, size_available, "%hd", frame_i[i]);
if (cnt <= 0 || cnt >= size_available)
{
printf("Error - snprintf failed or string too short\n");
free(s);
return(0);
}
size_available -= cnt;
tmp += cnt;
}
printf("%s\n", s);
free(s);
return 0;
}
Here is what you need to do:
When allocating space for the string, give 6 bytes for each array element because you can have at most 6 digits in a signed 16-bit integer (like, -32768) and you are storing digits as a character, not a number.
You have to adjust the next position for writing according to the digit-length of the number.
Remember that when you use snprintf, the unwritten characters in the string will be '\0', so you would not get a continuous string if you leave gaps in the string while writing to it.
Also note that the second argument value in snprintf, the n must be one greater than the maximum width number you want to put (for accommodating '\0'.
This would work in your case:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int16_t frame_i[5] = {10, -26, 35, 7, -35};
size_t i, j;
char *s = malloc(5*3+1);
for(i = 0, j=0; i<5; i++) {
snprintf(s + j, 4, "%hd", frame_i[i]);
if(frame_i[i]<0 && frame_i[i]<=-10)
j+=3;
else if(frame_i[i]<0)
j+=2;
else if(frame_i[i] < 10)
j+=1;
else
j+=2;
}
printf("%s",s);
return 0;
}
This code doesnt seem to work for me. it outputs the number 17 which is obviously wrong.the counter should go up if it encounters numbers like 5, 15, 25, 50 ect.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void) {
int i;
int counter;
char num[4322];
for (i = 1; i < sizeof(num); i++){
num[i] = i;
if ( strstr(&num[i], "5")){
counter = counter + 1;
}
}
printf("%d", counter);
return 0;
}
You didn't convert the numbers to strings, and you passed what are not a null-terminated strings to strstr().
You also forgot to initialize counter.
You should check the digits one-by-one. Try this:
#include <stdio.h>
int main(void) {
int max = 4322;
int target = 5;
int i, cur, counter = 0;
for (i = 1; i <= max; i++) {
for (cur = i; cur > 0; cur /= 10) {
if (cur % 10 == target) counter++;
}
}
printf("%d\n", counter);
return 0;
}
There are many problems in this code.
char num[4322];
This is an array of 4322 characters. You probably didn't want that, I'm not sure why it is here.
num[i] = i;
This is invalid, because you cannot assign large numbers to a char. This will not convert the number to a string, this will convert the number to a char which is different. So 5 does not become "5" but it becomes \x05.
strstr(&num[i], "5")
This will search for "5", but since the array is not nul-terminated, it is incorrect. Also note that you are storing
int counter;
Note that counter is uninitialized. This is an error.
Here is a similar program, which is correct (but not "efficient" per se):
#include <stdio.h>
#include <string.h>
int main() {
int counter = 0; // initialize to 0
for (int i = 0; i < 4322; i++) {
// Put the number in a string
char buf[10];
snprintf(buf, sizeof(buf), "%d", i);
// Count 5s
for (char *p = buf; *p; p++) {
if (*p == '5') {
counter++;
}
}
}
printf("%d", counter);
}
Note that #MikeCAT's answer skips the int -> string conversion, which is somewhat unnecessary.
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