Loading all text lines into different tables dynamically located in c - c

Command:
the program reads the file and saves it in memory, treating each line as a subtitle (Note: to simplify the program, we can assume that we know the limit for the length of the line (say 1023 characters) and we know the limit for the number of lines (say 2048), but we expect that the lengths of individual lines can vary greatly, so we allocate the memory for each line dynamically during reading, writing the addresses of subsequent subtitles in the table)
I have a code that reads one line, but I don't know how to change it so that the program reads all the lines into different arrays and then reads the indicators into them into the next array
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLINE 1023
#define ROW 32
int main()
{
FILE *fp;
char *array;
size_t csize = ROW;
size_t cpos = 0;
int ch;
fp = fopen("plik.txt", "r");
array = malloc(ROW);
while((ch = fgetc(fp))!='\n'&& ch!='\r')
{
array[cpos++] = ch;
if(cpos == csize)
{
csize += ROW;
array = realloc(array, csize);
}
}
array[cpos] = 0;
fclose(fp);
free(array);
return 0;
}

Here I have example how you can initialize dynamicaly two dimentional array of floats.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
int x, y;
printf("Enter x\n");
scanf("%d", &x);
printf("Enter y\n");
scanf("%d", &y);
float** matrix = (float**)malloc(x * sizeof(float));
for (int i = 0; i < x; i++)
{
matrix[i] = (float*)malloc(y * sizeof(float));
}
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
int value = rand()%10000;
matrix[i][j] = (float)value / 100;
printf("%.2f ", matrix[i][j]);
}
printf("\n");
}
free(matrix);
}
Play a little bit with this code. You shouldn't have any problems to initialize every line with different length.

Related

Sort floating point values from a file (read/write)

I am writing a C program that should sort floats (increasingly). The values are saved in a file and then after the sort, the values are saved into the same file. I am using library functions to read and write. I am using radixsort to sort the floats.
This is the code I currently have. Rather than the array being populated with values from the file that I am reading, it is storing 0.000000 for every index. I am not sure where I am going wrong in my implementation.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
void swap(float *a, float *b, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
float tmp = a[i];
a[i] = b[i];
b[i] = tmp;
}
}
void radixSort(float array[], size_t count)
{
int numZeroes=0;
float tempArr1[count];
float * tempArr2 = tempArr1;
for (uint32_t radix=1;radix;radix<<=1){
uint32_t * intArray = (uint32_t *)array;
int count0=0;
int count1=0;
numZeroes=0;
for (int j=0; j<count; ++j)
numZeroes += !(intArray[j]&radix);
count1=numZeroes;
for (int j=0; j < count; ++j)
if (intArray[j]&radix){
tempArr2[count1]=array[j];
++count1;
}
else{
tempArr2[count0]=array[j];
++count0;
}
swap(tempArr2,array,count);
}
if (numZeroes<count){
memcpy( tempArr2+(count-numZeroes), array, numZeroes*sizeof(float));
for (int d=0,j=count-1;j>=numZeroes;j--,d++)
tempArr2[d]=array[j];
memcpy( array, tempArr2, count * sizeof(float));
}
}
int main(int argc, char *argv[]) {
FILE *fd, *writeFile;
int i = 0;
float number;
int elementnum = 0;
struct stat st;
int fd2;
fd=fopen(argv[1], "r");
fd2 = fileno(fd);
if(fd==NULL){
printf("Error opening file\n");
}
fstat(fd2, &st);
off_t size = st.st_size;
for(int j = 0; j < size/4; j++){
elementnum++;
}
float array[elementnum];
while(fscanf(fd, "%f", &number)==1) {
array[i] = number;
i++;
}
radixSort(array,elementnum);
for(int j = 0; j < elementnum; j++){
printf("%f\n", array[j]);
}
fclose(fd);
writeFile=fopen("argv[1]", "w");
for(int j = 0; j < elementnum; j++){
fprintf(writeFile, "%f\n", array[j]);
}
fclose(writeFile);
return 0;
}
At least these issues:
Code is assuming the size of the text file divided by 4 is the number of float. This is risky and error prone. #agus
Instead of fstat(fd2, &st);, count them
size_t elementnum = 0;
while(fscanf(fd, "%f", &number)==1) {
elementnum++;
}
rewind(fd);
float array[elementnum];
for (i=0; i < elementnum; i++) {
if (fscanf(fd, "%f", &number) != 1) {
puts("We have trouble reading the same on the 2nd pass");
exit(1);
}
array[i] = number;
}
radixSort(array, elementnum);
/ 4 might make sense with a binary file and using fread() to read float.
it is storing 0.000000 for every index
Writing float with "%f" is uninformative with small values. Better to use "%e" or "%g".
#include <float.h>
// fprintf(writeFile, "%f\n", array[j]);
fprintf(writeFile, "%g\n", array[j]);
// or better
fprintf(writeFile, "%.*g\n", FLT_DECIMAL_DIG, array[j]);

Initializes an array by a given size in random values between 1 and 500 in c

I have assignment to write program that sort an array and search for a specific number, that part I've already done, My problem is how to Initialize the array in the size that the user sets with random values ​​smaller than 500? I know how to do that with known size but not with unknown size?
example for input/output:
"Please enter the size of the array:
5"
This will help you.
int main(void)
{
int n,i;
n=rand()%500; // Get random value
int arr[n]; // Initialize the dynamic array
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
// Do your stuff
}
You can do something like this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void printArray(int* p, int size)
{
for (int j = 0; j < size; ++ j) printf("%d ", p[j]);
printf("\n");
}
int main(void) {
srand(time(NULL)); // Start with a random seed based on time
int n = 0;
printf("Which array size do you need?\n");
if (scanf("%d", &n) != 1 || n < 1)
{
printf("Wrong input\n");
exit(0);
};
printf("Creating random array of size %d\n", n);
int* p = malloc(n * sizeof(*p)); // Reserve memory
for (int j = 0; j < n; ++j) p[j] = rand() % 500; // Generate random numbers
printArray(p, n); // Print the result
free(p); // free the allocated memory
return 0;
}

How to repeat scanf() n times?

I ask the user to input two integers, n and x. After that, I need to ask them for a value for the a variable n times. I need to create a new a variable for each value. How do I do it? I have absolutely no idea.
Also, I need to do it in one line, so the input will be, for example, 50 30 21, not
50
30
21
Thanks.
#include <stdio.h>
int main (void) {
int a, n, x;
int i = 0;
scanf ("%d%d", &n, &x);
scanf ("%d", &a); /* what should I do here? */
}
Try this:
int arr[100]; // static allocation but you can also allocate the dynamically memory
printf("Enter the number for how many time repeat scanf()\n");
scanf("%d",&n);
for (int i = 0; i < n; i++)
{
scanf("%d",&arr[i]);
}
Try the below code:
#include <stdio.h>
int main (void) {
int a[100];
int n, x;
int i = 0;
scanf ("%d%d", &n, &x);//n cannot be greater than 100 in this case.
for(i = 0; i < n; i++)
{
scanf ("%d", &a[i]);
}
return 0;
}
Using dynamic memory:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int *a = NULL;
int n, x, i;
scanf("%d%d", &n, &x);
if (n <= 0) {
fprintf(stderr, "n must be > 0\n");
return 1;
}
a = malloc(n * sizeof(int));
if (a == NULL) {
fprintf(stderr, "failed to allocate memory for "
"%d integers\n", n);
return 1;
}
/* reading the user input */
for (i = 0; i < n; i++) {
scanf ("%d", &a[i]);
}
/* usage */
for (i = 0; i < n; i++) {
printf("a[%d] = %d\n", i, a[i]);
}
printf("x = %d\n", x);
free(a);
return 0;
}
After that, I need to ask them for a value for the a variable n times.
High Level Programming Languages and even Assembly Language (Conditional/Unconditional Jump) provide Loop constructs to a programmer. In computer programming, a loop is a sequence of instructions that is continually repeated until a certain condition is reached. In C/C++, we have for, while, do while loop constructs.
So, i order to ask a user for a value for n times, you can use for loop in your program. I have given an example below:
#include <stdio.h>
#define MAX_ARR_LEN 100
int main (void)
{
int a[MAX_ARR_LEN];
int n, x;
int i = 0;
scanf ("%d%d", &n, &x);
if (n > MAX_ARR_LEN) {
printf("You can't enter more than - %d\n", MAX_ARR_LEN);
return -1;
}
for(i = 0; i < n; i++) {
scanf ("%d", &a[i]);
}
return 0;
}
When you do scanf, it takes the input until the space character, which is a delimiter. You do not need to specify anything extra for that.
If you do not need to use the value of n again, you could use this code.
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int n, x, i;
scanf ("%d%d", &n, &x);
int *a = (int *) malloc (n * sizeof(int)); //This will allocate 'n' integer sized memory for 'a'
for(i = 0; i < n; i++) {
scanf ("%d", &a[i]);
}
}

Ordering floats read from file with quick select give segmentation fault

I have to use quick select to sort and write the first N elements of an array and write them on a text.
The problem is with the input file and the quantity of data I try to read from it.
I use a constant, N, to define the max quantity of number I want to read from the file, but so far it only reads and sorts up to 194 elements from the file. I should be able to do it with 10 million, however.
Here's the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#define N 194
float qselect(float *array,int ini, int fin, int k){
int i;
int st = ini;
float tmp;
//finding a pivot
for (i = 0; i < fin - 1; i++) {
if (array[i] < array[fin-1]) {
tmp = array[st];
array[st] = array[i];
array[i] = tmp;
st++;
}
}
//exchanging the pivot with the last element of the array
tmp = array[fin-1];
array[fin-1] = array[st];
array[st] = tmp;
//veryfing the pivot
if (k == st)
return array[st];
else if (st>k)
return qselect(array,ini,st,k);//search on the left
else
return qselect(array,ini+st,fin,k);//search on the right
}
int main(void)
{
FILE *input;
FILE *output;
int range;
//opening the files
input = fopen("numeros.txt","r");
output = fopen("out.txt","w");
printf("Select your N : ");
scanf("%d",&range);
float *array_x;
array_x = malloc(sizeof(float)*N);
float num;
int size=0;
for(int f=0;f<N; f++){
fscanf(input,"%f",&array_x[size]);
size++;
}
int i;
for (i = 0; i < range; i++) {
fprintf(output,"%f ", qselect(array_x,0, size, i));
}
fclose(input);
fclose(output);
free(array_x);
return 0;
}
If I try to define N=195 or more, the code doesn't work.

How to create a 2d array, the dimensions of which are specified by the user? (in C)

Here is my try. I am not totally sure about my manipulations with the pointer. Maybe this is why I am wrong, maybe there is some other case. I want to take the dimensions from the user and create a square matrix, make some manipulations with its elements, and display the original and results to the user. Last time I accomplished this by creating a 100x100 array, and specifying the end of each line, and end of lines by constants. Then I would print all the elements up to this constant. But it does not seem to be right to create a 100x100 array for 4x4 matrices. I could create a smaller array, but this does not seem to be the right solution to the problem. Is there a way in C to create a 2d array exactly the size specified by the users (it will be a square array). Thanks
#include <stdio.h>
#include <stdlib.h>
double * createMatrix(int dimentions);
void drawMatrix(double * matrix);
int main(void)
{
int n, i, j;
system("cls");
system("color 70");
system("pause");
puts("Enter the matrix's dimension");
scanf("%i", &n);
double * pmatrix = createMatrix(n);
for (i = 0; i < n; ++j)
for (j = 0; j < n; ++j)
{
printf("A%i%i: ", i + 1, j + 1);
scanf("%lf", pmatrix[i][j]);
getchar();
}
for (i = 0; i < n; ++i)
{
putchar('\n');
for (j = 0; j < n; ++j)
printf(" %lf ", &pmatrix[i][j]);
}
system("color 08");
return 0;
}
double * createMatrix(int n)
{
const int N = n;
const int N1 = N;
double matrix[N][N];
double * pmatrix = matrix;
return pmatrix;
}
You can create a matrix directly; you don't need a function for that. Replace the code
double * pmatrix = createMatrix(n);
by the regular way of declaring a 2-D array:
double matrix[n][n];
One more way of doing it using pointers.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
double **pmatrix;
int rowsize, colsize, i, j;
printf("Enter the number of rows: ");
scanf("%d",&rowsize);
printf("Enter the number of columns: ");
scanf("%d",&colsize);
//Allocate memory for 2D array
pmatrix = malloc(rowsize*sizeof(double*));
for(i=0;i<rowsize;i++)
{
pmatrix[i] = malloc(colsize*sizeof(int));
}
//Accepting the values
for(i=0;i<rowsize;i++)
{
for(j=0;j<colsize;j++)
{
printf("A %i %i: ", i + 1, j + 1);
scanf("%lf",&pmatrix[i][j]);
}
}
//Printing the values
for(i=0;i<rowsize;i++)
{
for(j=0;j<colsize;j++)
{
printf("%lf\t",pmatrix[i][j]);
}
printf("\n");
}
//Free the memory
for(i=0;i<rowsize;i++)
free(pmatrix[i]);
free(pmatrix);
return 0;
}

Resources