Generating Random Numbers in C and writing it to a text file - c

I've created a project that reads numbers from a text file and draws an isometric projection of it, but now I'm trying to create a program that generates numbers from 0-9 and writes them in the document. This is what my code looks like, but the document remains empty. I'm under the assumption that the error is either in my rand() function usage, or when I convert the integers to characters.
Thank you in advance for all the input, and I apologize if it's just an operator error. I'm pretty new to this stuff:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char str[10];
FILE *fptr;
int i;
int num;
char num2;
i = 0;
fptr = fopen("map.fdf", "w");
if (fptr == NULL)
{
printf("ERROR Creating File!");
exit(1);
}
while (str[i] != '\0')
{
num = rand() % 10;
num2 = num + '0';
str[i] = num2;
i += 1;
}
puts(str);
fprintf(fptr,"%s", str);
fclose(fptr);
return (0);
}

I don't understand your while loop, it seems to wait for some condition that it doesn't contain code to make happen.
Anyway, how about not re-inventing how to convert single-digit integers to characters, and instead using higher-level I/O functions to just print to the file? That's why they're there, after all. :)
for (int i = 0; i < 10; ++i)
{
fprintf(fptr, "%d", rand() % 10);
}
fprintf(fptr, "\n"); /* Probably nice to make it a line. */
If you really must make do without for, you can of course always manually transform it into a while loop:
int i = 0;
while(i++ < 10)
{
fprintf(fptr, "%d", rand() % 10);
}

Your "str" is uninitialized, but apparently has a '\0' character as it's first element, so the while loop does not execute.

FILE *fn;
int num, n, range;
printf("Enter number of positive integer:");
scanf("%d", &n);
printf("Enter max integer:");
scanf("%d", &range);
fn=fopen("number.txt", "w");
for (int i=0; i<n; ++i) {
num = (rand()%range) + 1;
fprintf(fn, "%d\n", num);
}
fclose(fn);

Related

Fibonacci number code with for-loop and if statement error

so i'm a beginner and trying to solve a small project about making fibonacci number.
The code essentially is about typing n (the sequence) and it will show you what value of fibonacci number in that n-sequence.
but of course the code went wrong, the code just stop until i type the n-sequence, and nothing being printed after that. Can anybody check my code pls?
#include <stdio.h>
int main(){
int n;
int seq[n];
int i;
printf("number of sequence for the fibonacci number that you want to find out (from 0)= ");
scanf("%d", &n);
for(i = 0; i <= n; i++){
if(i == 0){
seq[i] = 0;
}
else if(i == 1){
seq[i] = 1;
}
else if(i > 1){
seq[i] = seq[i-1] + seq[i-2];
}
}
if(i == n){
printf("the value in sequence %d is %d", n, seq[n]);
}
return 0;
}
You need to declare the variable length array seq after you entered its size
For example
int n;
int i;
printf("number of sequence for the fibonacci number that you want to find out (from 0)= ");
scanf("%d", &n);
int seq[n + 1];
The size of the array is specified as n + 1 because the user is asked to enter the fibonacci number starting from 0.
Also this for loop will be correct provided that the array has n + 1 elements.
for(i = 0; i <= n; i++){
It is better to write it like
for(i = 0; i < n + 1; i++){
And this if statement
if(i == n){
does not make a sense. Just output the value of the array element seq[n].
apparently, in the loop, you set the boarder as i<=n while the array seq[n] is with the size of n. So i must be less than n.
n is uninitialized. It contains a garbage value.
Don't use scanf() for reading user input. It is very error-prone. Just try typing some string and see what happens. Better use fgets() in combination with sscanf().
int n;
char input[255];
printf("Number of sequence: ");
fgets(input, sizeof input, stdin);
input[strcspn(input, "\n")] = '\0';
if (sscanf(input, "%d", &n) != 1) {
// Handle input error
}
int seq[n+1]; // Edited: n+1 because fib starts from 0
int i;
for (i = 0; i < n+1; i++) {
if (i == 0 || i == 1)
seq[i] = i;
else
seq[i] = seq[i-1] + seq[i-2];
}

String Sort and remove Duplicates

First I apologize for any mistype, for I am Brazilian and English is not my native language.
I am a freshman at my college and I got this algorithm to solve, from my teacher:
Make a program that creates a vector of n words, n being a size entered by the user (maximum 100). Your program should remove all duplicate words from the input vector and sort the words. Print the final vector without repeated and ordered words.
E.g. with 7 words to sort:
Input: 7 [enter]
hand ear leg hand hand leg foot
Output: ear foot hand leg
Note: Comment the program prints so that the output of the program is as shown in the example above (the numbers are separated by a spacebar, without space after last digit).
Note2: In case of invalid entry the program should print: "invalid entry" (all lower case).
Ok, I got it working but the I got confused with the notes and I can't find a way to fix the possible bugs, here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char word[100][100], aux[100];
int i, j, num;
printf("Type how many words you want to order: ");
do
{
scanf("%d", &num);
}while (num>100 || num<=0);
for(i=0; i<num; i++)
scanf("%s",&word[i]);
for (i = 0; i < num; i++) //loop to sort alphabetically
{
for (j = i+1; j < num; j++)
{
if ((strcasecmp(word[i], word[j]) > 0)) //swapping words
{
strcpy(aux, word[j]);
strcpy(word[j], word[i]);
strcpy(word[i], aux);
}
}
}
for (i = 0; i < num; i++) //loop to remove duplicates
{
if ((strcasecmp(word[i], word[i+1]) == 0)) //finding the duplicates
{
for (j = i+1; j < num; j++) //loop to delete it
strcpy(word[j], word[j+1]);
num--;
i--;
}
}
printf("\nWords sorted and without duplicates:\n");
for(i=0; i<num-1; i++)
printf("%s ", word[i]); //output with spacebar
printf("%s", word[num-1]); //last output without spacebar
return 0;
}
When I type a word with more than 100 characters, the Code::Blocks closes with an error, else it works fine. What do you think I should change?
The teacher uses a Online Judge (Sharif Judge) to evaluate if the code is right, and I got error in 3 of the tests (that are not specified), all of them were "Time Limit Exceeded". Maybe it has do to with the size of the matrix, or the problem with words >100.
Thanks in advance, Vinicius.
I guess you input sanity check is causing the issue.
As mentioned in the comment section.
If n is always < 100. Definitely your sorting is not causing any time limit exceeded.
Looks like the n is given something greater than 100 and your scanf is waiting and causing the issue. Also, make sure your input numbers are taken properly. If the input is > 100 print 'invalid entry'.
Something like below should work.
scanf("%d", &num);
if (num > 100)
printf("invalid entry");
for (i = 0; i < num; i++) {
scanf("%s", word[i]);
if (strlen(word[i])>100)
printf("invalid entry");
}
Hope it helps!
of course you will get an error if you use woerds more than 100 length casue you
have this line: char word[100][50], aux[100];
that means that you word length limit is set to 50. use word[100][100];
also you may not delete duplicates, just skip them in output
lol of course if youre using judge , you should not output any symbols except the answer, this means you should delete all lines, like :
printf("Type how many words you want to order: ");
and check the input format, and check limitations, i mean max word length , max amounts of words
try smth like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max_word_length = 101;
#define max_amount_of_words = 101;
int main() {
char word[max_amount_of_words][max_word_length] = {};
char aux[max_word_length];
int i, j, num;
scanf("%d", &num);
if (num < 0 || num > 100) {
printf("invalid entry");
return 0;
}
for (i = 0; i < num; i++) {
scanf("%s", word[i]);
}
for (i = 0; i < num; i++) {//loop to sort alphabetically
for (j = i + 1; j < num; j++) {
if ((strcasecmp(word[i], word[j]) > 0)) { //swapping words
strcpy(aux, word[j]);
strcpy(word[j], word[i]);
strcpy(word[i], aux);
}
}
}
bool is_joint = false;
for (i = 0; i < num; i++) { //loop to skip duplicates
if ((strcasecmp(word[i], word[i + 1]) != 0)) { //if there is a duplicate , we willnot output it
if(is_joint) printf(" ");
printf("%s ", word[i]);
is_joint = true;
}
}
return 0;
}
I got 100% on Judge, I fixed the code and looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char word[101][101],aux[101]; //a number higher than the limit to comparisons
int i,j,num;
scanf("%d",&num);
if(num<=0||num>100){ // if words < 0 or >100
printf("invalid input");
return 0;
}
for(i=0;i<num;i++){
scanf("%s",&word[i]); //read n words
if(strlen(word[i])>100){ //if word >100 caracters
printf("invalid input");
return 0;
}
for(j=0;j<strlen(word[i]);j++){
if (word[i][j]>=65&&word[i][j]<=90){
word[i][j]= word[i][j]+32; // if word is uppercase, make them lowcase
}
else if (word[i][j]>122||word[i][j]<97){// if word is different from alphabet lowercase
printf("invalid input");
return 0;
}
}
}
for(i=0;i<num;i++){
for(j=i+1;j<num;j++){
if((strcmp(word[i],word[j])>0)){ //loop to sort words
strcpy(aux,word[j]);
strcpy(word[j],word[i]);
strcpy(word[i],aux);
}
}
}
for(i=0;i<num-1;i++){
if((strcmp(word[i],word[i+1])!=0)){ // output words with spacebar, without the last one
printf("%s ",word[i]);
}
}
printf("%s",word[num-1]); // last word without spacebar
return 0;
}
Thank you everyone who tried to help, I've learned a lot with your suggestions!
This project is actually pretty tough assignment for a programmer who just
started in C.
Run this program in your computer.
Before running against the Judge, make sure you run many times with your manual inputs. Once you are happy with the tests, try against the Judge.
Like I said, the hardest part is storing the user's inputs according to spec (accepting space or newline characters in multiple lines).
#include <stdio.h>
#include <string.h>
int
main(void)
{
int iNumW, iIndex;
int iWCnt = 0;
int iC;
char caTemp[100];
char caWords[100][100];
char *cpDelimeter = " \n";
char *cpToken;
char *cp;
short sIsWord = 1;
char caGarbage[100];
scanf("%d", &iNumW );
fgets(caGarbage, sizeof caGarbage, stdin); //Remove newline char
//Get word inputs
while( iWCnt < iNumW )
{
fgets(caTemp, sizeof caTemp, stdin );
for( cpToken = strtok( caTemp, cpDelimeter ); cpToken != NULL; cpToken = strtok( NULL, cpDelimeter)){
cp = cpToken;
while( *cp ){
sIsWord = 1;
//Check if alphabet
if( !isalpha(*cp) ){
sIsWord = 0;
break;
}
cp++;
}
if( sIsWord ){
strcpy( caWords[iWCnt], cpToken );
//printf( "%s\n", caWords[iWCnt]);
iWCnt++;
if( iWCnt >= iNumW ) break;
} else {
printf("invalid entry.\n");
}
//printf("%d\n", iWCnt);
}
}
int i,j ;
for (i = 0; i < iWCnt; i++) {//loop to sort alphabetically
for (j = i + 1; j < iWCnt; j++) {
if ((strcasecmp(caWords[i], caWords[j]) > 0)) { //swapping words
strcpy(caTemp, caWords[j]);
strcpy(caWords[j], caWords[i]);
strcpy(caWords[i], caTemp);
}
}
}
for (i = 0; i < iWCnt; i++) { //loop to skip duplicates
if ((strcasecmp(caWords[i], caWords[i + 1]) != 0)) { //if there is a duplicate , we willnot output it
printf("%s ", caWords[i]);
}
}
return 0;
}

Redirecting input(text file) in C

so I can't seem to redirect an input so that my program reads it.
It says in the assignment that the program should NOT print anything to prompt for user input. As many numbers have to be read from stdin to test your programs, you are expected to use INPUT REDIRECTION to read the input from a file.
I have this main function:
int main(int argc, char const *argv[])
{
int arr[100];
for (int i = 0; i < SIZE; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
FILE* file = fopen("file_name.txt", "r");
int index = 0;
int k = 0;
while (!feof(file))
{
fscanf(file, "%d", &k);
arr[index] = k;
index++;
}
fclose(file);
file = fopen("file_name.txt", "r");
int i = 0;
fscanf(file, "%d", &i);
float size = i;
fscanf(file, "%d", &i);
int thresh_hold = i;
int load_factor = size / 2;
int j = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
}
else
{
while (!feof(file))
{
if (num_keys <= load_factor)
{
int check_valid_input= fscanf(file, "%d", &i);
if (check_valid_input != 0 || check_valid_input== -1)
{
insert_into_hashtable(i, size);
}
else
{
printf("\n invalid input:\n");
exit(1);
}
}
else
{
printf("\nError in inserting more numbers:\n");
exit(1);
}
}
fclose(file);
printHashMap(arr,size, thresh_hold);
}
}
How do I edit this main function so that it redirects seq.1 or any other text file to the C program? Any help would be appreciated!
Simply use stdin instead of file, but do not open stdin, and do not close it.
When calling a program like ./program < seq.1, the operating system will pass the content of seq.1 to your program as if it were inputed through the console. Hence, using stdin, which represents console input, will do the job.
Note that stdin is by default already opened when your program starts.
Your code is hardcoding the input file, so file redirection from the command line will not do anything. File redirection helps with stdin (console input), stdout (console output), and stderr (console error message output). See linuxcommand.org here for a tutorial.
So to make your code work with stdin, use scanf instead of fscanf. scanf takes input from FILE stdin, whereas fscanf takes input from a specified FILE. Using scanf will result in input from stdin, which can be redirected on the command line as described above. Similarly, if you want to use stdout, use printf instead of fprintf. Neither scanf or printf take a file parameter, but are the same as fscanf and fprint in other respects. See this stackOverflow article for some more explanation.
Here is how I would fix your code to read/write to stdin and stdout:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
// Not Needed: FILE* file = fopen("file_name.txt", "r");
int index = 0;
int k = 0;
while (!feof(stdin))
{
scanf("%d", &k);
arr[index] = k;
index++;
}
// fclose(file);
// file = fopen("file_name.txt", "r");
int i = 0;
scanf("%d", &i);
float size = i;
//printf("%d ", i);
scanf("%d", &i);
int thresh_hold = i;
//printf("%d ", i);
int load_factor = size / 2;
int j = 0;
//int check_valid_input = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
}
else
{
while (!feof(stdin))
{
if (num_keys <= load_factor)
{
int check_valid_input= scanf("%d", &i);
if (check_valid_input != 0 || check_valid_input== -1)
{
insert_into_hashtable(i, size);
}
else
{
printf("\n invalid input:\n");
exit(1);
}
}
else
{
printf("\nError in inserting more numbers:\n");
exit(1);
}
}
// fclose(file);
printHashMap(arr,size, thresh_hold);
}
}
To use stdin (and file redirection), you will not be able to close and reopen stdin and get the same data. It just does not work that way. So remove one of the read loops so you only read it once. The first loop reads it into array arr[], so the second loop should take the values from that array rather than re-reading it.
#include <stdio.h>
$include <stdlib.h>
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values [i] = 0;
hashMapLinear[i] = 0;
}
int index = 0;
int k = 0;
while (!feof(stdin))
{
scanf("%d", &k);
arr[index] = k;
index++;
}
float size = arr[0];
int thresh_hold = arr[1];
int load_factor = size / 2;
int j = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
exit(-1);
}
else
{
int i;
for(i=2; i<index; i++) // reuse values stored in arr[]
insert_into_hashtable(arr[i], size);
printHashMap(arr,size, thresh_hold);
}
}
You may want to use open() instead of fopen(). Open returns a non-negative integer representing the lowest numbered unused file descriptor. With file descriptors it is much easier to redirect your output.
The shell command already redirects input to your program. There is a file pointer called stdin already opened in your program that represents the standard input. When you use < seq.1, it pipes the contents of the file in the standard input of your program, which you can read using fgetc or scanf.
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
int index = 0;
int k = 0;
while (!feof(stdin))
{
fscanf(stdin, "%d", &k);
arr[index] = k;
index++;
}
}
This program reads all the numbers from the standard input and stores them in your array. Notice you don't need to open or close it, it is already open when your main is called and closed at the end of your program execution.

Fscanf Seg Error

Working on a project where I have to have a file that is generated numbers. First line is a generated int. Followed by a floats (separate lines). (I'm doing it separate lines because I feel it makes more sense as I have to read it two different ways for the bin packing problems which I need this for... Like one way of reading one at a time and another storing it in an array.. But want to get this down first)
Getting a seg fault when I try to read my file for a float after reading an int. Edit: Error occurs in readOffline.
int randomFunction()
{
FILE *fp;
int i;
fp = fopen("theItems.txt", "w" );
if (fp == NULL)
printf("Error: file can't be opened.\n");
srand(time(NULL) );
int random_number = rand();
printf("Random Number %d\n", random_number);
fprintf(fp,"%d",random_number);
fclose(fp);
fp = fopen("theItems.txt", "a");
int numberOfItems = rand();
printf("NumberOfItems: %d\n",numberOfItems);
for(i = 0; i < 10; i++)
{
fp = fopen("theItems.txt", "a");
float number = (float)rand()/(float)(RAND_MAX);
fprintf(fp,"%f",number);
fprintf(fp,"%s", "\n");
fclose(fp);
}
return numberOfItems;
}
void readOffline( int numberOfItems)
{
FILE *fp;
int n = 0,i;
float nu = 0.00;
fp = fopen("theItems.txt", "r");
if (fp == NULL)
printf("Error: file can't be opened.\n");
fseek(fp,SEEK_SET,0);
fscanf(fp,"%d",&n);
printf("Number read: %d\n", n);
float array[numberOfItems];
// for(i = 0; i < 3; i++)
// {
fscanf(fp,"%f",&nu);
// array[i] = nu;
// }
fclose(fp);
printf("Int:%d\n", n);
int j;
// for(j = 0; j < 3; j++)
// printf("Float Number:%f\n", array[j]);
}
int main()
{
int numberOfItems = randomFunction();
readOffline(numberOfItems);
return 0;
}
Just trying to get an understanding why it causes a seg error when I // it out I can get it to read my int but sometimes it isn't the right int read. But yeah.
Please let me know if I need any more details or need to be more clear anywhere
You have multiple issues in your code:
You open the output file multiple times in randomFunction(), you even leak a stream handle and leave it open.
You do not exit the function when fopen() returns NULL. The rest of the code invokes undefined behavior if fp == NULL.
The same problem is present in readOffline(): if fp == NULL, you should return from the function immediately.
you do not output a linefeed after the first random number in the output file.
you always output 10 random numbers.
most importantly: the random number returned by the randomFunction() is potentially huge, allocating an array with local storage larger than a few megabytes is likely to cause undefined behavior. Try and reduce the maximum random number of values.
Here is a proposed correction:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int randomFunction(void) {
FILE *fp;
int i;
fp = fopen("theItems.txt", "w");
if (fp == NULL) {
printf("Error: file can't be opened.\n");
return -1;
}
srand(time(NULL));
int random_number = rand();
printf("Random Number %d\n", random_number);
fprintf(fp, "%d\n", random_number);
int numberOfItems = 1 + rand() % 100; /* between 1 and 100 */
printf("NumberOfItems: %d\n", numberOfItems);
for (i = 0; i < numberOfItems; i++) {
float number = rand() / (float)(RAND_MAX);
fprintf(fp, "%f\n", number);
}
fclose(fp);
return numberOfItems;
}
void readOffline(int numberOfItems) {
FILE *fp;
int n = 0, i;
fp = fopen("theItems.txt", "r");
if (fp == NULL) {
printf("Error: file can't be opened.\n");
return;
}
fscanf(fp, "%d", &n);
printf("Number read: %d\n", n);
float array[numberOfItems];
for (i = 0; i < numberOfItems; i++) {
if (fscanf(fp, "%f", &array[i]) != 1)
break;
}
fclose(fp);
printf("Int:%d\n", n);
for (int j = 0; j < i; j++) {
printf("Float Number %d: %f\n", j, array[j]);
}
}
int main(void) {
int numberOfItems = randomFunction();
readOffline(numberOfItems);
return 0;
}
Note that I kept your semantics: the random number at the start of the file is not the number of floating point values that follow. I suspect it should be?
I would say that depending on the particular compiler that you are using, then this could be a problem in setting up the actual array. This is (as an example) discussed in Variable Sized Arrays vs calloc in C From the discussions, you should use calloc and free. Another point is that you need to make sure that your value is greater than 3 and not too big. Since the array is only in the local scope of readOffline(), you should not connect it to the variable numberOfItems.
float array[3];
for(i = 0; i < 3; i++)
{
fscanf(fp,"%f",&nu);
array[i] = nu;
}

C Reading numbers from file into array

hey so i m trying to read numbers from text file and put them into an array but ive been getting weird numbers when i try to print them. text file looks like:
45
77
8
...
i guess theres something wrong with the loop i m using but i cant seem to find out what.
thanks for your help!
code:
#define MAX_ARRAY_SIZE 20
int main(int argc, char * argv[])
{
FILE *myFile;
int myArray[MAX_ARRAY_SIZE];
//char filename[32];
//printf("enter filename\n");
//scanf("%s", filename);
myFile = fopen("asdf.txt", "r");
if (!myFile) {
printf("cant open file\n");
return 1;
}
int status;
int i = 0;
while ((status = fscanf(myFile, "%2d", &myArray[i])) == 1 && i < MAX_ARRAY_SIZE - 1) {
++i;
}
fclose(myFile);
int a;
for (a = 0; i < MAX_ARRAY_SIZE; ++i) {
printf("%d ", myArray[i]);
}
printf("\n");
return 0;
}
The problem is in your print loop:
for (a = 0; i < MAX_ARRAY_SIZE; ++i)
There is no guarantee you are reading MAX_ARRAY_SIZE values. Also, if you ar using 'a' as your loop iterator, then you need to use 'a'. Your loop should be:
for (a = 0; a < i; ++a)
printf("%d ", myArray[a]);
You also do not need a field-width in your format-specifier, fscanf(myFile, " %d", &myArray[i])) will do.
Try this
while ((status = fscanf(myFile, "%d\n", &myArray[i])) == 1 && i < MAX_ARRAY_SIZE - 1) {
++i;
}
True... I have not seen print loop code.. Sorry.
Problem is in print loop not fscan, please ignore my answer

Resources