here is my code. I am trying generate random alphabet but i see same letters.
example: (YHTGDHFBSHXCHFYFUXZWDYKLXI) How can i fix it? just i need mixed alphabet not same letters. Thank you so much.
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void random_string(char * string, unsigned length)
{
/* Seed number for rand() */
srand((unsigned int) time(0));
int i;
for (i = 0; i < length; ++i)
{
string[i] = rand() % 26 + 'A';
}
string[i] = '\0';
}
int main(void)
{
char s[26];
random_string(s, 26);
printf("%s\n", s);
return 0;
}
The operation you are looking for is called a shuffle or a permutation. It is not sufficient to call a random-letter function 26 times, since, as you see, you can generate duplicates.
Instead, start with the string "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and perform a shuffle operation. If you want to learn by doing such things from scratch, I recommend reading about the Fisher-Yates Shuffle then crafting an implementation on your own.
You can do this by having a pool of available characters, and taking one from the pool. Please note that your target string was too short to accomodate the string terminator. Similar to Fisher Yates shuffle.
Edit: changed the types to size_t.
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define LENGTH 26 // the cipher key length
void random_string(char * string, size_t length)
{
char pool[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
size_t poolsize = strlen(pool);
size_t index;
size_t i;
srand((unsigned)time(NULL));
for(i = 0; i < length && poolsize > 0; ++i)
{
index = rand() % poolsize; // a random index into the pool
string[i] = pool[index]; // take that character
pool[index] = pool[--poolsize]; // replace it with the last pool ...
} // ... element and shorten the pool
string[i] = '\0';
}
int main(void)
{
char s[LENGTH + 1]; // adequate length
random_string(s, LENGTH);
printf("%s\n", s);
return 0;
}
Program output:
QYMUSFALIZCXGONBJRETHPVKDW
// why program get errors this line? (unused variable cipher_text)
char *cipher_text, msg[255];
You declare cipher_text but you only use msg.
You could declare only:
char msg[255];
Copy paste from cplusplus.com/reference
The pseudo-random number generator is initialized using the argument
passed as seed.
For every different seed value used in a call to srand, the
pseudo-random number generator can be expected to generate a different
succession of results in the subsequent calls to rand.
Two different initializations with the same seed will generate the
same succession of results in subsequent calls to rand.
If seed is set to 1, the generator is reinitialized to its initial
value and produces the same values as before any call to rand or
srand.
In order to generate random-like numbers, srand is usually initialized
to some distinctive runtime value, like the value returned by function
time (declared in header ). This is distinctive enough for most
trivial randomization needs.
/* srand example */
#include <stdio.h> /* printf, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
int main ()
{
printf ("First number: %d\n", rand()%100);
srand (time(NULL));
printf ("Random number: %d\n", rand()%100);
srand (1);
printf ("Again the first number: %d\n", rand()%100);
return 0;
}
Related
I'm trying to get an array to be initialized in a function. The initialized array should contain a set of random numbers within a certain range when working as intended. Is this possible in C?
#include <time.h> //time func for seed init
#include <stdlib.h> //srand/rand funcs
#include <stdio.h> //Library for printf function
#define LIMIT 100
void myFunction(int array[], int arrayIndexMaxSize){
for (int index = 0; index < arrayIndexMaxSize; index++){
array[index] = rand() % LIMIT; //Where limit is randomly produced from 0 - Limit inclusive
printf("array[%d] of arrayIndexMaxSize(%d) = %d\n", index, arrayIndexMaxSize, array[index]); //prints out th$
}
}
void main(){
srand(time(0)); //initializes kinda random number generator
int array[50]; //If known at runtime or compile time, must be at block scope meaing inside {curly} braces of any$
myFunction(array, 50);
}
I have this exercise that i can't understand and i hoped somebody could help me with it.
Develop a function that receives a table of strings, each one
with a maximum of 40 characters, and return the index of the largest of them. Note: The function receives a two-dimensional table, with the first dimension of the table not specified.
My question is how do i use the two dimensional table in this exercise i normally only used the a normal array to do strings, and after that what is exactly the index of a string? Is its lenght? Because if it is i know how to do the problem using the function strlen. I just dont understand how the table will work. If somebody can please help me (sorry for my bad english).
code
This means, your function should work like this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int func (char table[][40], int numentries) {
...
}
int main (void) {
int index;
char example[][40] = {
"this",
"is",
"an",
"example",
"with",
"seven",
"words"
};
index = func(example, 7);
printf("The longest word has index %d\n", index);
exit(EXIT_SUCCESS);
}
(maybe it should even be 41 instead of 40 to have space for the zero-byte, depending if this is already counted in or not in the specification)
Now, each entry of the table has at most 40 characters, but the number of entries is unspecified and has to be passed in a separate argument.
You can iterate over the table from i = 0 up to numentries and find the element with the greatest length. The corresponding i is the index you have to return.
Here is an example, make sure you understand what was done- if something is unclear- ask. I hope this helps:
Note that if there are multiple max the index returned will be for the first string of that length.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int GetLongestString(char sArr[][40], int row)
{
int i = 0;
int max = 0;
int maxindex = -1;
for(i= 0 ; i< row; ++i) /*to check each row*/
{
if(max < strlen(&sArr[i][0])) /*gives the add of each rows string beginning for
the strlen function */
{
max = strlen(&sArr[i][0]);/*get the max value and store it for later
checks*/
maxindex = i;/* save the index of max length*/
}
}
return maxindex;
}
int main()
{
int res = 0;
char array[2][40] ={"all", "hello"};
char array2[2][40] ={"hello", "all"};
res = GetLongestString(array,2);
printf("%d\n", res);
res = GetLongestString(array2,2);
printf("%d\n", res);
return 0;
}
Good luck!
I am a complete beginner.
I have a function which converts an int to an array.
#include <math.h>
#include <stdio.h>
int *convertIntArray(int number) {
int n = log10(number) + 1;
int i;
int *numberArray = calloc(n, sizeof(int));
for (i = 0; i < n; ++i, number /= 10) {
numberArray[i] = number % 10;
}
return numberArray;
}
I'd like to initialise an array named sample in my main function, by passing an integer to the convertIntArray function. My pseudocode looks like:
int main(int argc, char *argv[]) {
int sample = convertIntArray(150);
// rest of main function
But obviously this doesn't work. What is the correct way to do this?
The array is allocated by the converIntArray function and a pointer to its first element is returned. You can store this pointer to array in main if you define array with the appropriate type:
int main(int argc, char *argv[]) {
int *sample = convertIntArray(150);
// rest of main function
Note however that you cannot tell the size of the array pointed to by array from the pointer and the values. You should return either always allocate the maximum size, which is 10 int or return the size some other way, for example as the first element of the array, which you would then allocate with an extra element.
The first thing to note in your code is that you don't include a prototype for function log10() which I guess should be in <math.h>. Or you have done it, but didn't show it in your snippet of code. This is bad posting in StackOverflow, because that leaves us in the dilema of deciding if you made a mistake (by not including it, which will give you undefined behaviour, so, please edit your question, including a minimal, complete and verifiable example.
In case I had to write your function, I should not use log10() because it is a floating point function and you can select the wrong number of digits to allocate in case there's some rounding error in the calculation. Anyway, I'd try to use as less support functions as possible, by changing your interface to this one:
unsigned *number2digits(
unsigned *array_to_work_in, /* the array is provided to the function */
size_t array_size, /* the size of the array, in number of elements */
unsigned source_number, /* the number to be converted */
unsigned base); /* the base to use for conversion */
This approach doesn't force you to include the math library only for the log10() function, and also doesn't make use of the dynamic allocator routines malloc() and calloc(), and the compiler optimises it better if the function doesn't call more external/library functions. In case (see below) you want to use the function on an already allocated array, you don't have to rewrite it. Also, the numbering base is a good thing to pass as parameter, so you are not stuck to base 10 only numbers.
Another error is that you are returning an int * (pointer to int) and you assign the value to a variable of type int (this is a mistake that should have given you a compiler error).
A valid (and complete, and verifiable) example code should be:
#include <stdio.h>
#include <stdlib.h>
unsigned *number2digits(
unsigned *array_to_work_in, /* the array is provided to the function */
size_t array_size, /* the size of the array, in number of elements */
unsigned source_number, /* the number to be converted */
unsigned base) /* the base to use for conversion */
{
size_t i;
for (i = 0; i < array_size; i++) {
array_to_work_in[i] = source_number % base;
source_number /= base;
}
/* if, at this point, source_number != 0, you made an error
* on estimating array size, as the number doesn't fit in
* array_size digits. In case of error, we return NULL to
* indicate the error. */
return source_number == 0 ? array_to_work_in : NULL;
}
#define NUMBER 150000
#define N 10
#define BASE 38
int main()
{
unsigned my_array[N]; /* 10 digits for a base 38 is enough for a 32 bit integer */
unsigned *r = number2digits(my_array, N, NUMBER, BASE);
if (!r) {
fprintf(stderr, "Error, number %u does not fit in %u base %u digits\n",
NUMBER, N, BASE);
exit(EXIT_FAILURE);
}
printf("%u =/base %u/=>", NUMBER, BASE);
int i; /* we use int here as size_t is unsigned and we could
* not detect the loop exit condition */
for (i = N-1; i >= 0; i--) {
printf(" %u", r[i]);
}
printf("\n");
exit(EXIT_SUCCESS);
}
it shows:
$ pru
150000 =/base 38/=> 0 0 0 0 0 0 2 27 33 14
$ _
I'm trying to create a char array made of some letters and numbers (the function was way more complex initially but i kept simplifying it to figure out why it doesn't work properly). So i have a char array in which i put 2 chars, and try to add some numbers to it.
For a reason i can't figure out, the numbers do not get added to the array. It might be really stupid but I'm new to C so here's the simplified code. Any help is much appreciated, thanks!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char some_string[20];
char *make_str() {
some_string[0] = 'a';
some_string[1] = 'x';
int random = 0;
int rand_copy = 0;
random = (rand());
rand_copy = random;
int count = 2;
while ( rand_copy > 0 ) {
rand_copy = rand_copy / 10;
++count;
}
int i=2;
for (i=2; i<count; i++) {
some_string[i] = random%10;
random = random/10;
}
return (some_string);
}
int main(int argc, const char *argv[]) {
printf("the string is: %s\n",make_str());
return 0;
}
You have many problems:
resulting string is not zero-terminated. Add some_string[i] = '\0'; to fix this
character (char) is something like "a letter", but random % 10 produces a number (int) which when converted to character results in control code (ASCII characters 0-9 are control codes). You'd better use some_string[i] = (random % 10) + '0';
you're using fixed length string (20 characters), which may be enough, but it could lead to many problems. If you are a beginner and haven't learn dynamic memory allocation, than that's ok for now. But remember that fixed-length buffers are one of top-10 reasons for buggy C-code. And if you have to use fixed-length buffers (there are legitimate reason for doing this), ALLWAYS check if you are not overrunning the buffer. Use predefined constants for buffer length.
unless the whole point of your excercise is to try converting numbers to strings, use libc function like snprintf for printing anything into a string.
don't use global variable (some_string) and if you do (it's ok for a small example), there is no point in returning this value.
Slightly better version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF_LENGTH 20
char some_string[BUF_LENGTH];
char *make_str() {
some_string[0] = 'a';
some_string[1] = 'x';
int random = rand();
int rand_copy = random;
int count = 2;
while (rand_copy > 0) {
rand_copy = rand_copy / 10;
++count;
}
int i;
for (i = 2; i < count; i++) {
/* check for buffer overflow. -1 is for terminating zero */
if (i >= BUF_LENGTH - 1) {
printf("error\n");
exit(EXIT_FAILURE);
}
some_string[i] = (random % 10) + '0';
random = random / 10;
}
/* zero-terminate the string */
some_string[i] = '\0';
return some_string;
}
int main(int argc, const char *argv[]) {
printf("the string is: %s\n",make_str());
return 0;
}
I am looking for a (relatively) simple way to parse a random string and extract all of the integers from it and put them into an Array - this differs from some of the other questions which are similar because my strings have no standard format.
Example:
pt112parah salin10n m5:isstupid::42$%&%^*%7first3
I would need to eventually get an array with these contents:
112 10 5 42 7 3
And I would like a method more efficient then going character by character through a string.
Thanks for your help
A quick solution. I'm assuming that there are no numbers that exceed the range of long, and that there are no minus signs to worry about. If those are problems, then you need to do a lot more work analyzing the results of strtol() and you need to detect '-' followed by a digit.
The code does loop over all characters; I don't think you can avoid that. But it does use strtol() to process each sequence of digits (once the first digit is found), and resumes where strtol() left off (and strtol() is kind enough to tell us exactly where it stopped its conversion).
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int main(void)
{
const char data[] = "pt112parah salin10n m5:isstupid::42$%&%^*%7first3";
long results[100];
int nresult = 0;
const char *s = data;
char c;
while ((c = *s++) != '\0')
{
if (isdigit(c))
{
char *end;
results[nresult++] = strtol(s-1, &end, 10);
s = end;
}
}
for (int i = 0; i < nresult; i++)
printf("%d: %ld\n", i, results[i]);
return 0;
}
Output:
0: 112
1: 10
2: 5
3: 42
4: 7
5: 3
More efficient than going through character by character?
Not possible, because you must look at every character to know that it is not an integer.
Now, given that you have to go though the string character by character, I would recommend simply casting each character as an int and checking that:
//string tmp = ""; declared outside of loop.
//pseudocode for inner loop:
int intVal = (int)c;
if(intVal >=48 && intVal <= 57){ //0-9 are 48-57 when char casted to int.
tmp += c;
}
else if(tmp.length > 0){
array[?] = (int)tmp; // ? is where to add the int to the array.
tmp = "";
}
array will contain your solution.
Just because I've been writing Python all day and I want a break. Declaring an array will be tricky. Either you have to run it twice to work out how many numbers you have (and then allocate the array) or just use the numbers one by one as in this example.
NB the ASCII characters for '0' to '9' are 48 to 57 (i.e. consecutive).
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main(int argc, char **argv)
{
char *input = "pt112par0ah salin10n m5:isstupid::42$%&%^*%7first3";
int length = strlen(input);
int value = 0;
int i;
bool gotnumber = false;
for (i = 0; i < length; i++)
{
if (input[i] >= '0' && input[i] <= '9')
{
gotnumber = true;
value = value * 10; // shift up a column
value += input[i] - '0'; // casting the char to an int
}
else if (gotnumber) // we hit this the first time we encounter a non-number after we've had numbers
{
printf("Value: %d \n", value);
value = 0;
gotnumber = false;
}
}
return 0;
}
EDIT: the previous verison didn't deal with 0
Another solution is to use the strtok function
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "pt112parah salin10n m5:isstupid::42$%&%^*%7first3";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," abcdefghijklmnopqrstuvwxyz:$%&^*");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " abcdefghijklmnopqrstuvwxyz:$%&^*");
}
return 0;
}
Gives:
112
10
5
42
7
3
Perhaps not the best solution for this task, since you need to specify all characters that will be treated as a token. But it is an alternative to the other solutions.
And if you don't mind using C++ instead of C (usually there isn't a good reason why not), then you can reduce your solution to just two lines of code (using AXE parser generator):
vector<int> numbers;
auto number_rule = *(*(axe::r_any() - axe::r_num())
& *axe::r_num() >> axe::e_push_back(numbers));
now test it:
std::string str = "pt112parah salin10n m5:isstupid::42$%&%^*%7first3";
number_rule(str.begin(), str.end());
std::for_each(numbers.begin(), numbers.end(), [](int i) { std::cout << "\ni=" << i; });
and sure enough, you got your numbers back.
And as a bonus, you don't need to change anything when parsing unicode wide strings:
std::wstring str = L"pt112parah salin10n m5:isstupid::42$%&%^*%7first3";
number_rule(str.begin(), str.end());
std::for_each(numbers.begin(), numbers.end(), [](int i) { std::cout << "\ni=" << i; });
and sure enough, you got the same numbers back.
#include <stdio.h>
#include <string.h>
#include <math.h>
int main(void)
{
char *input = "pt112par0ah salin10n m5:isstupid::42$%&%^*%7first3";
char *pos = input;
int integers[strlen(input) / 2]; // The maximum possible number of integers is half the length of the string, due to the smallest number of digits possible per integer being 1 and the smallest number of characters between two different integers also being 1
unsigned int numInts= 0;
while ((pos = strpbrk(pos, "0123456789")) != NULL) // strpbrk() prototype in string.h
{
sscanf(pos, "%u", &(integers[numInts]));
if (integers[numInts] == 0)
pos++;
else
pos += (int) log10(integers[numInts]) + 1; // requires math.h
numInts++;
}
for (int i = 0; i < numInts; i++)
printf("%d ", integers[i]);
return 0;
}
Finding the integers is accomplished via repeated calls to strpbrk() on the offset pointer, with the pointer being offset again by an amount equaling the number of digits in the integer, calculated by finding the base-10 logarithm of the integer and adding 1 (with a special case for when the integer is 0). No need to use abs() on the integer when calculating the logarithm, as you stated the integers will be non-negative. If you wanted to be more space-efficient, you could use unsigned char integers[] rather than int integers[], as you stated the integers will all be <256, but that isn't a necessity.