how to load random number from a txt file - c

hey guys i really want to know how to use this function to load random number from a .txt file which contains :
0 1 2 3 4 5 6 7 8 9
int main(int argc, char *argv[]) {
FILE* file = NULL;
int score[3] = {0};
file = fopen("test.txt", "r");
if (file != NULL)
{
fscanf(file, "%d %d %d", &score[0], &score[1], &score[2]);
printf("Les meilleurs scores sont : %d, %d et %d", score[0], score[1], score[2]);
fclose(file);
}
return 0;
}
but the problem is i have to make the computer choose a sequence of number randomly
maybe with srand(time(NULL));
i really appreciate your help :D

Getting a random number from a text file containing numbers 0-9 (inclusive) is slower than using srand and rand. Seed srand with the current time and call rand with %10 to get a (mostly) random number.
#include <stdlib.h> // Contains srand
#include <time.h> // Contains time
srand(time(NULL));
rand()%10;
However, if you're trying load random lines from a text file, I'd suggest reading all the lines into an ARRAY of size LINES and then calling ARRAY[rand()%LINES] to access a random index of that array, which would be the same as accessing a random line of the text file.

Unless you HAVE to get the number from the file, you can always do srand, rand etc and take the result modulo 10.

Related

how to know the secret number from srand(time(0))

I had a network security class in my university.
And there is a challenge for finding a secret number.
Here is the code
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
void init() {
setbuf(stdin, NULL);
setbuf(stdout, NULL);
}
int main() {
init();
srand(time(0));
int secret = 0;
puts("Your secret: ");
scanf("%d", &secret);
if(secret == rand()) {
system("/bin/sh");
} else {
puts("failed");
}
}
I actually could not understand my professor's explanation.
Anyone can explain the meaning of this code, and how can i find the secret number?
Technically you shouldn't be able to find the "secret" number - that's the whole point of the exercise: the "secret number" is generated using a strong PRNG seeded with a more-or-less random set of bits coming from the system clock.
Theoretically, if you have complete knowledge about the system - i.e. you both know the specific PRNG implementation used and the exact value used to seed it (the result of the time() call) - you should be able to guess the number simply by seeding another instance of the same PRNG and getting the next random int from it.
In this specific case, as the attacker you have complete control of the execution of the code and you should be able to predict the value returned from time() with very good accuracy (it is only a second resolution), so if you can build a program on the same system, that takes the predicted time value, seeds it to the same srand() implementation and returns the first random int - you can guess the "secret number".
So maybe the point of the exercise is to show that PRNG security trivially depends on knowing to start when no one is looking - otherwise you aren't secure, and possibly to not use time() to seed srand() and instead rely on something actually robust, like /dev/urandom 🤷.
Pseudo random number generators rely on a seed to generate their random numbers: if you use the same seed, you'll get the same sequence of "random" numbers.
See here:
Consider this code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
srand(0);
printf("random number 1: %d\n", rand());
printf("random number 2: %d\n", rand());
printf("random number 3: %d\n", rand());
printf("random number 4: %d\n", rand());
return 0;
}
Running the program (a.out) multiple times always generates the same numbers:
marco#Marcos-MacBook-Pro-16 Desktop % ./a.out
random number 1: 520932930
random number 2: 28925691
random number 3: 822784415
random number 4: 890459872
marco#Marcos-MacBook-Pro-16 Desktop % ./a.out
random number 1: 520932930
random number 2: 28925691
random number 3: 822784415
random number 4: 890459872
marco#Marcos-MacBook-Pro-16 Desktop % ./a.out
random number 1: 520932930
random number 2: 28925691
random number 3: 822784415
random number 4: 890459872
marco#Marcos-MacBook-Pro-16 Desktop % ./a.out
random number 1: 520932930
random number 2: 28925691
random number 3: 822784415
random number 4: 890459872
Of course the exact numbers will differ on the exact implementation used to generate the numbers. So the sequence of numbers probably will be different on your system. Nevertheless, using the same seed will always result in the same sequence.
Real systems use a combination of "real" (based on physical randomness) random numbers + a pseudo random number generator simply because its way more efficient to generate random numbers that way.
These are usually cryptographically secure pseudorandom number generators because the numbers are used for cryptographic operations (cryptography heavily relies on randomness to work).
The basic idea is as long as the initial seed is "secret" (unknown) you can't work it back and determine the pre-defined sequence of numbers generated.
It is possible (and has been done) to work back the initial seed simply by looking at the numbers generated by a pseudorandom number generator.
Now on how to solve the exercise given by your professor:
The easiest way would be to "freeze" time to have a fixed seed value for the random numbers (as shown in my code example above).
Since there isn't an easy way to do that, you can print the current seed by running another program to just output the first random number generated (since that's the "secret"):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(0));
printf("the secret number is %d\n", rand());
return 0;
}
You can then use that number to "unlock" the program given by your professor.
However you have to do that within a second or less, since time() returns a new value every second.
The more reliable way would be to have your program input the "random" number as soon as you generated it.
Here's an example code of how you could do that:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
// where to put the "random" number on disk
const char *tmp_file = "/tmp/input";
// where the executable of your professor is
const char *executable = "/path/to/your/professors/executable";
void writeRandomNumberToDisk(const char *path, int number) {
char buf[128];
// convert int to string
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "%d\n", number);
FILE *fp = fopen(path, "w+");
fwrite(buf, strlen(buf), 1, fp);
fclose(fp);
}
int main(void) {
srand(time(0));
int secret = rand();
printf("the secret number is %d\n", secret);
writeRandomNumberToDisk(tmp_file, secret);
char buf[512];
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "/bin/sh -c 'cat %s | %s'", tmp_file, executable);
printf("Now executing %s\n", buf);
system(buf);
return 0;
}
Essentially, it writes the first "random" number to disk, then invokes the shell that will feed the "random" number into the program.
You can also bypass the file system entirely by using something like:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
// where the executable of your professor is
const char *executable = "/path/to/your/professors/executable";
int main(void) {
srand(time(0));
int secret = rand();
printf("the secret number is %d\n", secret);
char buf[512];
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "/bin/sh -c 'printf \"%d\\n\" | %s'", secret, executable);
printf("Now executing %s\n", buf);
system(buf);
return 0;
}

How to compare two text files in C and output the differences in a new text file

I am writing a program that inputs two text files
inputtxt1,
inputtxt2
and output
outputtxt file
In these two files information such as
input txt1
S00111111 5 6-Jul-19 09-Aug-19
S00800000 4 1-Jul-19 30-Aug-19
S00000000 1 1-Jul-19 30-Aug-19
input txt2
S00111111 3 6-Jul-19 09-Aug-19
S00222222 1 20-Jul-19 30-Aug-19
S00000000 1 1-Jul-19 30-Aug-19
I am writing a program to input these two txt files and output the differences in SQL queries and the values inside the bracket will change depends on the differences from these text files.
DELETE FROM TABLE WHERE TABLE=[] AND TABLE=[]
INSERT INTO TABLE (TABLE1,TABLE2,TABLE3,TABLE4) VALUES ([ ],[],'[2019-08-30] 00:00:00','[2019-07-01] 00:00:00');
DELETE FROM TABLE WHERE TABLE=[] AND TABLE=[4]
INSERT INTO TABLE (TABLE,TABLE) VALUES ([],[4]);
I wrote my draft in C so what I did id basically a while loop to read each of the line of the first file and each of the line of the second file and output the query.
Here are my two questions:
First it, unfortunately, output the file SQL 3 times, I think there is something wrong with my while loop.
Secondly, how would I make the program detect that specific character from specific line need to be printed in the query for example number 5 in the first line would detect and add to the value of one of the tables in the query.
/* This program will input two text files, output a text file with the differences*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
FILE *in1, *in2, *out;
int a, b;
void main (void)
{
int c;
char* singleline [33];
char* singleline2 [33];
in1 = fopen ("inputtest1.txt", "r"); /* reads from the first file */
in2 = fopen ("inputtest2.txt", "r"); /* reads from the second file */
out = fopen ("outputtest3", "w"); /* writes out put to this file */
// Menu //
printf ("TSC Support Program\n\n");
printf ("This program compare the two files and output the differences in SQL quries \n");
// if the file is empty or something went wrong!
if (in1 == NULL || in2 == NULL)
{
printf("********************Can Not Read File !**************************");
}
else
{
// Checking Every line in the first text file if it equals to the first line of the text file
while (!feof(in1)&&!feof(in2))
{
// a = getc(in1);
// b = getc(in2);
a = fgets(singleline, 33,in1);
b = fgets(singleline2, 33,in2);
if (a!=b)
{
printf("\n SQL will be printed\n");
fprintf (out,
"\n DELETE FROM BADGELINK WHERE BADGEKEY=[27] AND ACCLVLID=75"
"\nINSERT INTO BADGELINK (BADGEKEY,ACCLVLID,ACTIVATE,DEACTIVATE) VALUES ([27],75,'[2010-08-24] 00:00:00','[2010-12-17] 00:00:00'); \n"
"\n DELETE FROM BADGE WHERE BADGEKEY=[27] AND ISSUECODE=[75]"
"\nINSERT INTO BADGE (BADGEKEY,ISSUECODE) VALUES ([27],[1]);\n"
);
}
else
{
printf("Something went wrong");
}
}
}
fclose(in1);
fclose(in2);
fclose(out);
}
It prints the output 5 times
and then it says something went wrong. I am unsure what went wrong.
if (a != b) does not do what you think it is doing. Check strncmp() or memcmp() library functions.
But if you want to find out the first different character in two strings, the code below would do it for you.
Not tested properly, so take it as a quick prototype.
#include <stdio.h>
int strdiff(char *s1, char *s2){
char *p1 = s1;
while(*s1++ == *s2++)
;
if (s1 != s2)
return --s1-p1; /* we have s1++ in the while loop */
return -1;
}
int main(){
char *s1="S00111111 5 6-Jul-19 09-Aug-19";
char *s2="S00111111 3 6-Jul-19 09-Aug-19";
int i = strdiff(s1,s2);
printf("%d %c\n",i, s1[i]);
return 0;
}
Mind you, comparing two files line by line may turn out to be a bigger mission than it sounds if the two files you are comparing do not have exactly the same lines (with minor differences of course).

How to read every n lines from txt file in C

I am reading from a text file and the file is in the format
value1: 5
value2: 4
value3: 3
value4: 2
value5: 1
and then it repeats.
I know how to grab the data I need from one line, but I've searched everywhere and looked through various books and resources and I can't figure out a way to read from every 10 lines instead of one line.
This is what I have so far and I am aware that it has a couple mistakes and I have extra variables and it is incomplete but I am able to compile and all it does is print the first value from the file. my printf is mostly just a test to see what I'm reading from the file.
#include <stdio.h>
#include <math.h>
int main()
{
int line = 0;
int time = 0;
int switch0 = 0;
int switch1 = 0;
int switch2 = 0;
int switch3 = 0;
int pot = 0;
int temp = 0;
int light = 0;
FILE *infile = fopen("data.txt", "r");
FILE *outfile = fopen("matlab.csv", "w");
if (infile == NULL)
{
printf("Error Reading File\n");
exit(0);
}
fprintf(outfile, "Time,Switch0,Switch1,Switch2,Switch3,Potentiometer,Temperature,Light");
fscanf(infile, "time: %d\nswitch0: %d\nswitch1: %d\nswitch2: %d\nswitch3: %d\npotentiometer: %d\n temperature: %d\n light: %d\n",
&time, &switch0, &switch1, &switch2, &switch3, &pot, &temp, &light) != EOF;
printf("%d\n %d\n %d\n %d\n %d\n %d\n %d\n %d\n", time, switch0, switch1, switch2, switch3, pot, temp, light);
}
tl;dr how to read every 10 lines of text file and save into array
Thanks in advance
I know how to grab the data I need from one line
Well that's a good start. If you can read one line, you can read one line n times, right?
I've searched everywhere and looked through various books and resources and I can't figure out a way to read from every 10 lines instead of one line.
It's just more of the same. You could, for example, write a function that reads exactly one line and returns the data. Then call that function the requisite number of times.
If you really want to read all the data from n lines at once, you can do that to. Instead of your code:
fscanf(infile, "time: %d\n", &time[100]);
you can make the format string more extensive:
fscanf(infile, "time: %d\nswitch1: %d\nswitch2: %d\npotentiometer: %d\n",
&time, &switch1, &switch2, &potentiometer);
The \n is just another character to fscanf() -- you don't have to stop reading at the end of one line.
Be careful with this approach, though. It leaves you open to problems if you have a malformed file -- everything will break if one of the lines you expect happens to be missing or if one of the labels is misspelled. I think you'd be better off reading one line at a time, and reading both the label and the value, like:
fscanf(infile, "%s %d\n", &label, &value);
Then you can look at the string in label and figure out which line you're dealing with, and then store the value in the appropriate place. You'll be better able to detect and recover from errors.

Append Random Text without Repetition for File (C)

I have 5 list of name
char *name[] = {"a","b","c","d","e"};
and I have 3 files
char path1[PATH_MAX+1]
snprintf(path1, PATH_MAX+1, "%sfile1.txt",dirname);
FILES *filename1 = fopen(path1, "w")
.
.
.
char path3[PATH_MAX+1]
snprintf(path3, PATH_MAX+1, "%sfile3.txt",dirname);
FILES *filename3 = fopen(path3, "w")
What I want is to randomly append a,b,c,d,e (one of them per file) into three of those files without repetition.
What I have right now is (example from one of them)
srand(time(NULL));
int one = rand()%5;
char path1[PATH_MAX+1];
snprintf(path1, PATH_MAX+1, "%sfile1.txt",dirname);
FILES *filename1 = fopen(path1, "w");
fputs(name[one],filename1);
fclose(filename1);
However, sometimes it is still possible where my file1.txt and file3.txt both contain b (same alphabet from name)
Questions
Did I miss something to make sure that all the random result always unique?
Is it also efficient tho to have 6 lines of code to create one file and append a random name inside it? I'm just wondering if I have to create like 20 files, I will write 120 lines that basically almost the same, just different in number (filename1 to filename3)
Thank you.
To get a unique sequence of characters, you can draw them from a diminishing pool. For example, after you have picked the a, it is removed from the pool. Of course, the pool must be at least as big as the number of files you want to print.
A simple way to implement this sort of picking is to pick a char from the pool, move the last character from the pool to the place of the picked character and decrease the pool size by one.
If you see a lot of repetition of code, especially if the only difference is a variable name along the lines of filename1, filename2, filename3 and so on should ring a bell that you should use an array: FILE *file[NFILE]. Be aware, though, that you can only have a certain number of files open at a time.
In your case, you want to write a single character to a file. There's no need to have multiple file s open simultaneously: Open a file, pick a char, write it to the file, close e file. Then process the next file.
The program below does what you want, I think.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define NFILES 10
int main()
{
char pool[] = "abcdefghij"; // Available chars as array
int npool = sizeof(pool) - 1; // Pool size minus terminating '\0'
int i;
if (npool < NFILES) {
fprintf(stderr,
"Not enough letters in pool for %d files.\n", NFILES);
exit(1);
}
srand(time(NULL));
for (i = 0; i < NFILES; i++) {
int ipick = rand() % npool; // position of pick
char pick = pool[ipick]; // picked char
char fname[20];
FILE *f;
pool[ipick] = pool[--npool]; // remove pick from pool
snprintf(fname, sizeof(fname), "file-%03d.txt", i);
f = fopen(fname, "w");
if (f == NULL) {
fprintf(stderr, "Could not create %s.\n", fname);
exit(1);
}
fprintf(f, "%c\n", pick);
fclose(f);
}
return 0;
}

Sum of numbers contained in strings

Given a text file, for example:
cdcd dcdaqw cdcd KKAN 89 bxb hqhq1bhA
100uuz
cnkx
n jk xjx100mc
...
.+1+
I want to find the sum of all the numbers contained in the various strings:
In the given example, I want to sum 89 100 1 100 1.
I made many attempts at this(IE, fscanf of each string and trying to save the int values in an array), but they all failed.
So this is fairly straightforward. At every position in the file we ask "is there a number here?". If there is, print it out. If there isn't try starting at the next character.
Based on how we understand fscanf() works, we'll test each character at most twice.
Code
#include <stdio.h>
#include <stdbool.h>
int main() {
FILE * fd = fopen("in.txt", "r");
while (true) {
unsigned number;
int rc = fscanf(fd, "%u", &number);
if (rc == EOF)
break;
else if (rc == 0)
fseek(fd, 1, SEEK_CUR);
else if (rc == 1)
printf("%u\n", number);
}
}
Input File
cdcd dcdaqw cdcd KKAN 89 bxb hqhq1bhA
100uuz
cnkx
n jk xjx100mc
...
.+1+
Output
89
1
100
100
1
Next steps
It should be fairly obvious how to extend this to report the sum, instead of the numbers themselves.
You could be using strtol
You have an example at the bottom of the page which does pretty much what you want. You're only going to need to manually skip the non-digit characters

Resources