Generation of 20 random nums in c - c

#include <stdio.h>
#include <time.h>
int main(int argc,char *argv[])
{
int i;
int array[20];
srand(time(NULL));
for (i=0; i<20; i++)
array[i] = rand()%8999 + 1000;
char *fname = argv[1];
FILE *fp;
fp = fopen(fname,"w");
fwrite(array,sizeof(int),20,fp );
fclose(fp);
return 0;
}
my program should generate a sequence of 20 random numbers within a range of 1000 to 9999. I need to create an array of 20 nums, sort it and transfer to the file passed at cmd line... But, it says Segmentation fault

Your formula for getting the random values is also wrong:
With this code:
rand()%9999 + 1001;
you will get values from [1001, 11000]. When you are claiming you want a range from [1000, 9999].
Try to solve this for a simpler case, lets say a dice from [1, 6] will be:
rand()%5 + 1
The other problem is your for loop:
Remove the for loop and you should be fine. You don't need that for loop to print the array. Check the rewind function if you really need to do something like that.

First check the return value of fopen.
Then:
fwrite(array,sizeof(int),20,fp );
You are not moving your array pointer. Use something like:
fprintf(fp, "%d\n", array[i]);
Also:
array[i] = rand()%9999 + 1001;
What if the value yielded by rand()%9999 is 9998? I think then 9998 + 1001 is no longer between 1000 and 9999. Also how can rand()%9999 + 1001 yields 1000?

for (i=0; i<20; i++)
array[i] = rand()%8999 + 1000; // change random Number logic
for (i=0; i<20; i++)
fprintf(fp,"%d\t",array[i]); // change fwrite(array,sizeof(int),20,fp );
see fprintf()

First problem, the rand calculation is false, if you want an integer between 1000 and 9999, then it should be :
array[i] = rand()%9000 + 1000; // 9000%9000 = 0 ...
Then, your call to fwrite writes the whole content of the array buffer, seen as a set of sizeof (int) long substrings. Since odds are quite low that you will end up with valid character encoding, when you will open your file with a text editor to see the results, you will only have gibberish data ... Thus, your whole for loop is useless (you will print 20 times the whole content of array subsequently to your file).
Here, what you could do is a for loop with a call to fprintf to write the array[i] number in a human readable format or just stick with your single call to fwrite.
Then, I would like to say that you do not test the return value of your function calls.
It can be a source of errors so be very careful with this. I think of the whole file operation functions (fopen, fwrite).
Then, what if argv[1] doesn't exist ? When the call to fopen will be run, you'll have a segmentation fault ... Here is a little checking you could add :
if (argc > 1) {
fname = argv[1];
} else {
fname = NULL;
}

Related

C: Read ints from file and store in pointer array

I am trying to read integers from a file and store them in an array. Then, I want to write those values to a different file. Reading an writing are done in a separate file from the main file, where the array was created. I cannot change the function's arguments (this is for an assignment, so the array argument must be int** ppPerm). The function is called, and the array originally created, in another file's main function. The file I am reading from looks like this:
15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Where 15 is how many numbers will follow. So the chronological order of functions is:
Array Perm is created in the main function of the main file (int* Perm = NULL). It is passed into readP()
readP(In, &Perm);
The numbers from the file are read and stored in Perm. The same variable Perm is then passed into writeP().
writeP(Out, Perm, permLength);
Perm is read and written to a different file.
I cannot change either of those lines. Somewhere along the road the array is screwed up. Here is readP().
int readP(FILE* In, int** ppPerm) {
int numElements = 0;
fscanf(In, "%d", &numElements);
*ppPerm = (int*)calloc(numElements, sizeof(int));
int i;
for (i = 0; i < numElements; i++) {
fscanf(In, "%p", &ppPerm[i]);
}
return numElements;
}
Right now, the array is completely unreadable. For whatever reason, the numbers stored are something like 0x0 then a random jumble of hexadecimals. The array is then used in writeP() to write the values to a different file:
void writeP(FILE* Out, const int* pPerm, int permLength) {
int i = 2;
for (i = 0; i < permLength; i++) {
fprintf(Out, "%d ", pPerm[i]);
}
return;
}
int* pPerm is the same array that was passed into readP(). For some reason, using debugging, I see that pPerm contains completely different values than ppPerm did, and in some cases it seems half empty. What exactly is wrong with my functions? Why can I not store the numbers in the array correctly? And why does the array keep messing up between readP() and writeP()?
Don't cast the result of calloc() or malloc() in C! It can hide errors.
int i;
for (i = 0; i < numElements; i++) {
fscanf(In, "%p", &ppPerm[i]);
}
Since you want to read integers the format string should be "%i" or "%d". To get to the Pointer to the memory you have allocated use *ppPerm:
size_t i; // variables that hold an index into or the size
// of objects in memory should be of type size_t.
for (i = 0; i < numElements; i++) {
fscanf(In, "%p", &(*ppPerm)[i]);
}

How to use more than one dynamic allocation on C programming?

I'm making a program that reads two sets of data (float) from two different .txt files, and then it transfers these data to two different arrays, which will be used in further calculations. However, when I try to use dynamic allocation more than once, something goes wrong and the data seem not to be stored in the array.
The following simplified program seems to be working fine:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float *VarA;
int n = 0;
int *counter;
int i;
FILE *input1;
input1 = fopen("C:\\Users\\...test.txt","r");
VarA = (float*)calloc(20001, sizeof(float));
for(i = 0; i < 20001; i++)
{
fscanf(input1,"%f",&VarA[i]);
printf("%f\n",VarA[i]);
}
free(VarA);
fclose(input1);
return 0;
}
it successfully shows the data stored in the array VarA. However, if I introduce a new array to count the number of lines in the file (which is necessary for my further calculations), I just get the value 0.000000 from every array element:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
float *VarA;
int n = 0;
int *counter;
int i;
FILE *input1;
input1 = fopen("C:\\Users\\...test.txt","r");
counter = (int*)calloc(100000, sizeof(int));
while(fscanf(input1,"%f",&counter[n]) != EOF)
{
n++;
}
free(counter);
printf("n = %i\n", n);
VarA = (float*)calloc(n, sizeof(float));
for(i = 0; i < n; i++)
{
fscanf(input1,"%f",&VarA[i]);
printf("%f\n",VarA[i]);
}
free(VarA);
fclose(input1);
return 0;
}
I know that I can avoid using another array to count the number of lines. The point is that every time I use another array, for any purpose, I get the same result. For instance, if I don't use an array to count the number of lines, but I make another one to store my other set of data, one of these arrays just won't present the data after the reading. I tried to modify my program several times in order to find the source of such behavior, but without success.
(At least) two major problems: first,
counter = (int*)calloc(100000, sizeof(int));
while(fscanf(input1,"%f",&counter[n]) != EOF) {
n++;
}
free(counter);
is basically saying "Grab me a chunk of memory, fill it with data as I read the file, then throw it away without ever using it." Probably not what you intended. Then,
VarA = (float*)calloc(n, sizeof(float));
for (i = 0; i < n; i++) {
fscanf(input1,"%f",&VarA[n]);
printf("%f\n",VarA[n]);
}
free(VarA);
which says, "Grab a big chunk of memory, then read data from after the end of the file I just read everything from, put it there, then throw it away."
If you want to read the data from the same file again, you'll have to close it an reopen it (or "seek" to the start). And if you want to do anything with it, you'll have to do it before free()ing the memory you loaded it into.
counter = (int*)calloc(100000, sizeof(int));
// ^--- `int*` ^--- `int`
// v--- `int` pointer
while(fscanf(input1,"%f",&counter[n]) != EOF)
// ^--- `float` designator
Do you see any discrepancies here? Your code allocates ints, then passes a pointer to those ints to fscanf telling it they're floats (using the %f designator). According to the C standard draft n1570, section 7.21.6.2p10 this constitutes undefined behaviour:
If this object does not have an appropriate type, or if the result of the conversion cannot be represented in the object, the behavior is undefined.
My suggestion would be to use the * assignment suppression modifier here, for example:
while (fscanf(input1, "%*f") != EOF) n++;
or, alternatively
while (fscanf(input1, "%f", &(float){0}) != 1) n++;
Note also how I've changed the check from EOF to 1. You can find more information about the return values of fscanf here (which you really should read before using any scanf-related function... and stop guessing, because guessing in C can be harmful).
Additionally, you need to rewind your file once it reaches EOF, otherwise every call to fscanf following this loop will return EOF:
rewind(input1);
P.S. Don't cast malloc in C. This goes for calloc and realloc, too. There's a lot of this quoted stuff that has opengroup manuals of its own; I'll leave it as an exercise to you to find (and read) the opengroup manuals.

fseek creates infinite loop at run time

WHAT THE CODE DOES: I read a binary file and sort it. I use a frequency array in order to do so.
UPDATES:it does do the loop, but it doesn`t write the numbers correctly...
That is the code. I want to write on file after reading from it. I will suprascript what is already written, and that is okey. The problem is I have no error on compiling, but at run time it seems I have an infinite loop.
The file is binary. I read it byte by byte and that`s also the way I want to write it.
while(fread(readChar, sizeof(readChar)/2, 1, inFile)){
bit = atoi(readChar);
array[bit] = array[bit] + 1;
}
fseek(inFile, 0, SEEK_SET);
for( i = 0; i < 256; i++)
while(array[i] > 0){
writeChar[0] = array[i]; //do I correctly convert int to char?
fwite(writeChar, sizeof(readChar)/2, 1, inFile);
array[i] = array[i] -1;
}
The inFile file declaration is:
FILE* inFile = fopen (readFile, "rb+");
It reads from the file, but does not write!
Undefined behavior:
fread() is used to read a binary representation of data. atoi() takes a textual represetation of data: a string (a pointer to an array of char that is terminated with a '\0'.
Unless the data read into readChar has one of its bytes set to 0, calling atoi() may access data outside readChar.
fread(readChar, sizeof(readChar)/2, 1, inFile);
bit = atoi(readChar);
Code it not reading data "bit by bit" At #Jens comments: "The smallest unit is a byte." and that is at least 8 bits.
The only possible reason for an infinite loop I see is, that your array is not initialized.
After declaration with:
int array[256];
the elements can have any integer value, also very large ones.
So there are no infinite loops, but some loops can have very much iterations.
You should initialize your array with zeros:
int array[256]={0};
I don't know the count of elements in your array and if this is the way you declare it, but if you declare your array like shown, than ={0} will initialize all members with 0. You also can use a loop:
for(int i=0; i < COUNT_OF_ELEMENTS;i++) array[i] = 0;
EDIT: I forgot to mention, that your code is only able to sort files with only numbers within.
For that, you have also to change the conversion while writing:
char writeChar[2]={0};
for( int i = 0; i < 256; i++)
while(array[i] > 0){
_itoa(i,writeChar,10);
fwrite(writeChar, sizeof(char), 1, inFile);
array[i] = array[i] -1;
}
File content before:
12345735280735612385478504873457835489
File content after:
00112223333334444455555556777778888889
Is that what you want?

Large numbers, sums, and data conversions

I've been pouring over my code (which does not work) now for quite some time. It is for a Project Euler problem in which one is given a very large sum to find, and then required to print the first ten digits of said sum. (The problem can be found here: https://projecteuler.net/problem=13)
I have run several 'tests' where I add print commands to see various values at various points in the code. When I run the code, I have gotten anything from symbols to ten digit numbers that should be single digits.
Anyways. My question is this: is this a type conversion issue or is there some other glaring issue with my method that I'm missing? I've been studying type conversions trying to find a fix, but to no avail.
Thank you for any help!
The code is as follows:
// this is a program to find a very large sum of many very large numbers
#include <stdio.h>
#include <math.h>
int main()
{
//declare all ints needed
int i;
int j;
int d; // digit, need to add 48
int placesum; // sum of addition in _'s place (1's, 10's, 10000's)
int place; // final place value
int c = 0, tens = 1, otherc; // counters for start finder
int a = 0; // another counter
//declare all arrays
char numarray[101][51]; //array of strings containing all 100 numbers
char sum[100];
printf("please save data to largesumdata.txt\n\n press enter when ready");
getchar();
// THE PROBLEM- I don't know how to get my data into my program // FIXED
// using fscanf()
FILE *pf; // declare a pointer to the file
pf = fopen("largesumdata.txt", "r"); // trys to open file // "r" means read only
if(pf == NULL)
printf("Unable to open file, sorry Jar\n");
else
{
for(j = 0; j < 100; j++)
fscanf(pf, "%s\n", &numarray[j]); // fscanf(pointer, data type, location)
}
//TESTING
//printf("You have reached point A\n");//POINT A WAS REACHED
//TESTING
//TESTING
//printf("Check1, %c\n", numarray[45][23]);
//TESTING
//TESTING
//printf("%c\n", numarray[90][22]);//Can successfully call characters from array
//TESTING
// (Brute force attempt) //I NEVER MESS WITH numarray WHY IS IT CHANGING
for(i = 49; i >= 0; i--)
{
//printf("%d\n", d);
for(j = 0; j < 100; j++)
{
d = (int)numarray[j][i] - 'o';
//printf("%d\n", d);
//holdup// d -= 48; // ASCII conversion // could also write "d = d-48"
//printf("%d\n", d);
placesum += d; // could also write "placesum = placesum + d"
//printf("%d\n", placesum);
}
place = placesum % 10;
placesum = placesum / 10; // takes "10's place" digit for next column
// now need to put 'int place' into 'char sum'
sum[i+5] = (char)place+'0'; // ASCII conversion // "+5" for extra space //HERE not properly stored in sum
}
//TESTING
//printf("Check2, %c\n", numarray[45][23]);
//TESTING
//TESTING
//printf("You have reached point B\n");//POINT B WAS REACHED
//TESTING
// find out where sum starts
for(c=0; c<10; c++)
if(sum[c] != '0')
break;
//TESTING
//printf("You have reached point C\n"); //POINT C WAS REACHED
//TESTING
otherc = 4-c;
printf("The first 10 digits of the sum of all those f***ing numbers is....\n");
printf("%d-%d-%d-%d-%d-%d-%d-%d-%d-%d", sum[otherc, otherc+1, otherc+2, otherc+3, otherc+4, otherc+5, otherc+6, otherc+7, otherc+8, otherc+9]);
//%c-%c-%c-%c-%c-%c-%c-%c-%c-%c //copy and paste purposes
//%d-%d-%d-%d-%d-%d-%d-%d-%d-%d // ^^^^^
getchar();
return 0;
}
P.S. I apologize if my plethora of notes is confusing
You are using wrong form to print an array in C.
sum[otherc, otherc+1, otherc+2, otherc+3, otherc+4, otherc+5, otherc+6, otherc+7, otherc+8, otherc+9] -> This actually decays to sum[otherc+9] because C treats , as an operator.
To print value at each array index, you should use it like this: sum[otherc], sum[otherc+1], sum[otherc+2],..
To read more about C's , (comma) operator, you can begin here
In your printf as I explained above, the first format specifier %d gets sum[otherc + 9], since sum[otherc,...,otherc+9] is actually a single number and that is otherc + 9th index of array sum. You do not provide anything to print for other format specifiers, hence you get garbage.
After a while I revisited my code, and realized that I was working with numbers upwards of 10 million. I had a mix of int, long int, and long long int variables declared.
I re-analyzed which was which, and made sure that all variables could handle the data it needed to (after looking at this handy link, showing what max integer sizes are for different data types.
Before I had been using the wrong ones, and going over the max values returned incorrect values, causing my program to crash during run time.
Lesson here: Check your data types!

C What is up with my Matrix Reader?

so I am trying to make a matrix reader that will take a text file that contains only data for a NxN matrix such as:
10 9 8 7
6 5 4 3
2 1 0 1
Read the test file into a dynamic multidimensional array. The program will not have headers, so it will need to read the entire file in order to obtain # of rows/cols.
Once I have all the data in my array I then will be able to manipulate how I want (i.e. swapping columns/rows, reversing order, etc).
At this point I am just trying to get my program to simply output the array as it appears in the test file once the entire matrix has been read in.
Here is what I have written so far:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
int i=0;
int j=0;
scanf("%d", &n);
int **array;
array = malloc(n * sizeof(int *));
if(array == NULL) {
printf("Out of memory\n");
exit(1);
}
for(i = 0; i < n; i++) {
array[i] = malloc(n * sizeof(int));
if(array[i] == NULL) {
printf("Out of memory\n");
exit(1);
}
}
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
int k;
scanf("%d", &k);
array[i][j] = k;
printf("%d ", array[i][j]);
}
}
}
And running this gives me output:
9 8 7 6 5 4 3 2 1 0 1 1 1 1 1 1 1 1 1 1 1 1... repeating 1's...
I am not sure what is wrong with my code I have been staring at it for a solid hour and have made 0 progress.
Because my output prints out about 100 different ints I feel that my problem lies in my printing loops, and I feel like it has something to do with int n, but I am not sure how to deal with this.
Any help with be greatly appreciated! Thanks.
The issue is as follows: The first number that is obtained from your file is 10 and that is being stored inside the int n close towards the beginning. That value defines the width and height of your multi-dimensional array, your matrix. You then ask for further values from that file, exactly 10 * 10 many times.
The file, however, only has 4 * 3 - 1 = 11 numbers left in it. It provides them all, right into the int k. Those values get stored inside your matrix, printed. After the 11th (or 12th if you count the first 10) the scanf starts failing. As it fails, it returns the value EOF == -1 but you do not recognize that.
Failure leaves the k as it is, although I am not sure whether it is guaranteed to remain what it previously was, since as far as I know, k could very well have another memory location allocated for itself with each cycle, since (again) as far as I know it gets cleared at the end of each loop. In your case, it does keep its value, luckily I would say, and that gets stored/printed.
In the end, you should have exactly 100 numbers printed, because of that 10 at the very beginning.
Even if you had an additional 4 at the very beginning, you'd end up with a matrix that has a wild last line with all 1s.
If you want to have a 3 by 4 matrix in your hands, consider making your file as the following example:
3 4
10 9 8 7
6 5 4 3
2 1 0 1
Then read the first value into an int n and then second one into an int m. Make first memory allocation with malloc( n * sizeof * array );, then the secondary allocations with malloc( m * sizeof ** array );.
You could also alternatively omit reading anything, deduce how many rows and columns your matrix should have by reading the amount of new-line '\n' occurrences in your file (plus one), as well as amount of numbers there are on a single line.
Edit:
Okay, let's show this you could also part: This is just an example, I'll be using a pair of scanfs for counting both the amount of lines that have at least one number inside and amount of numbers on a single line.
...
int n = 0;
int m = 0;
int discardable;
while ( scanf( "%d", &discardable ) == 1 ) {
// as long as a number has been successfully read
n++;
if ( scanf( "%*[^\n]" ) != 0 )
// discard everything until a '\n'
// and if you fail to encounter a '\n' anywhere until the file ends...
break;
}
// rewind back to the beginning of the file
rewind ( stdin );
while ( scanf( "%d", &discardable ) == 1 ) {
// as long as a number has been successfully read
m++;
if ( scanf( "%*[ \t]" ) != 0 || stdin->_ptr[0] == '\n' )
// discard every ' ' or '\t'
// if you rather get carried until the end of file, break
// else, if the upcoming character is '\n', again, break
break;
}
rewind ( stdin );
...
There you have it, n and m here should be storing the height and width of the matrix you should have, respectively.
This is just a way to do it, I can see why many could potentially just hate this, because I have made use of the FILE structure, and referred to _ptr, but whatever. I personally would prefer this any day over carrying a temporary character array and read from it.

Resources