This file needs to read a text file with numbers on each line, and preload the values from the text file into myArray. It also needs to read the integer for arraySize, so that it can be used to calculate the mean and median. The code is in c, but the teacher uses c++ file names and doesn't want us t change it. I also want to total the numbers, but when executed it doesn't print anything.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "Utils.cpp"
int main(void)
{
//declare variables
int myArray[]={};
// declare a string to hold the name of the file
// that will be read into your statsArray
char statsFile[] = "2005.txt"; /* file to be read in */
int arraySize = getFileSize(statsFile); /* determine size of file */
//dynamically declare statsArray based on size of file
int *statsArray = (int*)malloc(sizeof(int)*arraySize);
// initialize arrays with zero values
initializeArray(myArray, arraySize);
//load array from file
loadArray(myArray, arraySize, statsFile);
// sum stats array
int total=0;
for(int x=0;x<myArray[arraySize-1];x++){
total+=myArray[x]; //adds each element of array to total
}
printf("%i",total);
Here is the utils.cpp that was provided.
#include <stdio.h>
int getFileSize(char fileName[])
{
FILE *fr; /* declare the file pointer */
int c; /*Nb int (not char) for the EOF */
int newlineCount = 0;
// open the file to count the lines
fr = fopen(fileName, "rt");
// count the newline characters
while ( (c=fgetc(fr)) != EOF)
{
if (c =='\n')
newlineCount++;
}
return newlineCount;
}
void loadArray(int list[], int size, char fileName[])
{
FILE *fr; // declare the file pointer
int count = 0; // running line count
char line[80];
fr = fopen(fileName, "rt");
while(fgets(line, 80, fr) != NULL)
{
// get a line, p to 80 chars fr. done if NULL
sscanf(line, "%i", &list[count]);
count++;
}
}
void initializeArray(int list[], int size)
{
for (int i = 0; i < size; i++)
{
list[i] = 0;
}
}
void sortArray(int list[], int size)
{
int tempNumber;
for (int i = 0; i < size; i++)
{
for (int j = i +1; j < size; j++)
{
if(list[i] > list[j])
{
tempNumber = list[i];
list[i] = list[j];
list[j] = tempNumber;
}
}
}
}
Related
I have a text file I want to upload into a pointer array but I can't find any references besides 2D arrays or languages other than C.
My input.txt:
marbels
fruit
vegetables
marshmellow sprinkle
coffe beans
My source.c (my question is located in the int main(void){})
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX_LEN 1000
void sort(size_t size, char* data[]) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (strlen(data[j]) < strlen(data[j + 1])) {
char* temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
}
void printArray(size_t size, char* data[]) {
for (int i = 0; i < size; i++) {
printf("%s ", data[i]); //%c -> %s
}
}
int main(void) {
char* data[1000]; //I want the array to hold maximum 1000 characters
FILE* file;
file = fopen("C:\\Users\\EXAMPLE\\desktop\\input.txt", "r");
if (file == NULL) {
printf("File Error\n", file);
return 1;
}
//between these dashes in my issue with uploading the text from input to the char* data[1000];
int line = 0;
//if i build the program with this while-loop, I get an error
while (!eof(file) && ferror(file)) {
if (fgets(data[line], MAX_LEN, file) != NULL) { //error C6001: using uninitialized memory 'data'
line++;
}
}
fclose(file);
//
size_t size = sizeof data / sizeof data[0];
sort(size, data);
printArray(size, data);
return 0;
}
The error message:
I tried that while loop before and it wasn't great but only thing I could find at the time for this project.
As you have mentioned in your question, you will need to use a 2D array or otherwise you can use the malloc() function.
In your code you have a array with 1000 * sizeof(char) bytes. So bassically you have 1000 uninitialised pointers. But there are no pointers allocated that are able to store the lines of the file.
I am trying to print to the screen randomly in C. I am using random and time to generate random index and printing it but It definetely is not the way to do it. How do I print every element randomly to the screen in c?
Here is the code I have so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define leng 128
#define arr 10
int main(void)
{
char line[arr][leng];
char fname[20];
FILE *fptr = NULL;
int i = 0;
int tot = 0;
scanf("%s",fname);
fptr = fopen(fname, "r");
while(fgets(line[i], leng, fptr))
{
line[i][strlen(line[i]) - 1] = '\0';
i++;
}
srand(time(0));
for(int i = 0; i < 6; ++i)
{
printf("%s\n", line[rand()%10]);
}
return 0;
}
My random text file has 6 lines of code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define LEN 128 //Don't mind the capital, personal preference for defines
#define ARR 6 //Make this match the number of lines in your file
int main(void)
{
char line[ARR][LEN];
char fname[20];
int test[ARR] = {0}; //Added an array to test if index already created
int ind[ARR] = {0}; //Array to store index created randomly
int ind_done = 0; //Counter for index array
FILE *fptr = NULL;
int i = 0;
int tot = 0;
scanf("%s",fname);
fptr = fopen(fname, "r");
while(fgets(line[i], LEN, fptr))
{
line[i][strlen(line[i]) - 1] = '\0';
i++;
}
srand(time(0));
for(int i = 0; i < ARR; ++i)
{
printf("%s\n", line[rand()%ARR]);
}
//Keep creating indexes using rand till all unique indexes are created
while (ind_done<ARR) {
int i = rand()%ARR;
if (test[i] == 0) {
ind[ind_done] = i;
ind_done++;
test[i] = 1;
}
}
for(int i = 0; i < ARR; ++i)
{
printf("%s\n", line[ind[i]]);
}
return 0;
}
I have a matrix in a file like:
3
1 2 3
4 5 6
7 8 -9
where the first line indicates the square matrix order. I'm using the following code to read the file and store it into a vector (I have removed all if checks for sake of simplicity):
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int read_matrix_file(const char *fname, double *vector)
{
/* Try to open file */
FILE *fd = fopen(fname, "r");
char line[BUFSIZ];
fgets(line, sizeof line, fd);
int n;
sscanf(line, "%d", &n)
vector = realloc(vector, n * n * sizeof *vector);
memset(vector, 0, n * n * sizeof *vector);
/* Reads the elements */
int b;
for(int i=0; i < n; i++) {
// Read the i-th line into line
if (fgets(line, sizeof line, fd) == NULL) {
perror("fgets");
return(-1);
}
/* Reads th j-th element of i-th line into the vector */
char *elem_ptr = line;
for (int j=0; j < n; j++) {
if(sscanf(elem_ptr, "%lf%n", &vector[n*i+j] , &b) != 1) {
perror("sscanf");
return(1);
}
elem_ptr += b;
}
}
fclose(fd);
/* HERE PRINTS OK */
for(int i=0; i<n*n; i++)
printf("%i %f\n",i, vector[i]);
return n;
}
The read_matrix_file receives a filename and an array of doubles and fill the array, returning the matrix order. The expected usage can be seen in this code block.
int main(void)
{
const char *fname = "matrix.txt";
double *vector = malloc(sizeof * vector);
int n = read_matrix_file(fname, vector);
/* Here prints junk */
for(int i=0; i<n*n; i++)
printf("%i %f\n",i, vector[i]);
free(vector);
}
The issue is, the printf works fine inside the read_matrix_file but seems invalid in main.
I'm allocating the array outside the function and passing it by "reference", but I'm very suspecious of realloc, unfortunatelly I don't know how to fix or a better approach.
You are reallocating memory inside read_matrix_file() and storing the elements of the matrix in that memory region. But when you come out of the function, since the pointer vectoris a local variable, its new value is lost when you leave the function.
When you come back inside main() vector still points to the (now likely invalid) memory region that you had previously allocated with malloc().
You should either allocate large enough memory before calling read_matrix_file or pass a double pointer (**) if you want to modify the pointer and see the change reflected back in main()
What I meant is something like this:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int read_matrix_file(const char *fname, double **p_vector)
{
/* Try to open file */
FILE *fd = fopen(fname, "r");
char line[BUFSIZ];
fgets(line, sizeof line, fd);
int n;
sscanf(line, "%d", &n);
*p_vector = realloc(*p_vector, n * n * sizeof **p_vector);
double *vector = *p_vector;
memset(vector, 0, n * n * sizeof *vector);
/* Reads the elements */
int b;
for(int i=0; i < n; i++) {
// Read the i-th line into line
if (fgets(line, sizeof line, fd) == NULL) {
perror("fgets");
return(-1);
}
/* Reads th j-th element of i-th line into the vector */
char *elem_ptr = line;
for (int j=0; j < n; j++) {
if(sscanf(elem_ptr, "%lf%n", &vector[n*i+j] , &b) != 1) {
perror("sscanf");
return(1);
}
elem_ptr += b;
}
}
fclose(fd);
/* HERE PRINTS OK */
for(int i=0; i<n*n; i++)
printf("%i %f\n",i, vector[i]);
return n;
}
In main, call it with:
int n = read_matrix_file(fname, &vector);
EDIT: Please note that this code does not handle the failure of realloc() properly.
I have a .csv file that reads like:
SKU,Plant,Qty
40000,ca56,1245
40000,ca81,12553.3
40000,ca82,125.3
45000,ca62,0
45000,ca71,3
45000,ca78,54.9
Note: This is my example but in reality this has about 500,000 rows and 3 columns.
I am trying to convert these entries into a 2D array so that I can then manipulate the data. You'll notice that in my example I just set a small 10x10 matrix A to try and get this example to work before moving on to the real thing.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *getfield(char *line, int num);
int main() {
FILE *stream = fopen("input/input.csv", "r");
char line[1000000];
int A[10][10];
int i, j = 0;
//Zero matrix
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
A[i][j] = 0;
}
}
for (i = 0; fgets(line, 1000000, stream); i++) {
while (j < 10) {
char *tmp = strdup(line);
A[i][j] = getfield(tmp, j);
free(tmp);
j++;
}
}
//print matrix
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
printf("%s\t", A[i][j]);
}
printf("\n");
}
}
const char *getfield(char *line, int num) {
const char *tok;
for (tok = strtok(line, ",");
tok && *tok;
tok = strtok(NULL, ",\n"))
{
if (!--num)
return tok;
}
return 0;
}
It prints only "null" errors, and it is my belief that I am making a mistake related to pointers on this line: A[i][j] = getfield(tmp, j). I'm just not really sure how to fix that.
This is work that is based almost entirely on this question: Read .CSV file in C . Any help in adapting this would be very much appreciated as it's been a couple years since I last touched C or external files.
It looks like commenters have already helped you find a few errors in your code. However, the problems are pretty entrenched. One of the biggest issues is that you're using strings. Strings are, of course, char arrays; that means that there's already a dimension in use.
It would probably be better to just use a struct like this:
struct csvTable
{
char sku[10];
char plant[10];
char qty[10];
};
That will also allow you to set your columns to the right data types (it looks like SKU could be an int, but I don't know the context).
Here's an example of that implementation. I apologize for the mess, it's adapted on the fly from something I was already working on.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Based on your estimate
// You could make this adaptive or dynamic
#define rowNum 500000
struct csvTable
{
char sku[10];
char plant[10];
char qty[10];
};
// Declare table
struct csvTable table[rowNum];
int main()
{
// Load file
FILE* fp = fopen("demo.csv", "r");
if (fp == NULL)
{
printf("Couldn't open file\n");
return 0;
}
for (int counter = 0; counter < rowNum; counter++)
{
char entry[100];
fgets(entry, 100, fp);
char *sku = strtok(entry, ",");
char *plant = strtok(NULL, ",");
char *qty = strtok(NULL, ",");
if (sku != NULL && plant != NULL && qty != NULL)
{
strcpy(table[counter].sku, sku);
strcpy(table[counter].plant, plant);
strcpy(table[counter].qty, qty);
}
else
{
strcpy(table[counter].sku, "\0");
strcpy(table[counter].plant, "\0");
strcpy(table[counter].qty, "\0");
}
}
// Prove that the process worked
for (int printCounter = 0; printCounter < rowNum; printCounter++)
{
printf("Row %d: column 1 = %s, column 2 = %s, column 3 = %s\n",
printCounter + 1, table[printCounter].sku,
table[printCounter].plant, table[printCounter].qty);
}
// Wait for keypress to exit
getchar();
}
There are multiple problems in your code:
In the second loop, you do not stop reading the file after 10 lines, so you would try and store elements beyond the end of the A array.
You do not reset j to 0 at the start of the while (j < 10) loop. j happens to have the value 10 at the end of the initialization loop, so you effectively do not store anything into the matrix.
The matrix A should be a 2D array of char *, not int, or potentially an array of structures.
Here is a simpler version with an allocated array of structures:
#include <stdio.h>
#include <stdlib.h>
typedef struct item_t {
char SKU[20];
char Plant[20];
char Qty[20];
};
int main(void) {
FILE *stream = fopen("input/input.csv", "r");
char line[200];
int size = 0, len = 0, i, c;
item_t *A = NULL;
if (stream) {
while (fgets(line, sizeof(line), stream)) {
if (len == size) {
size = size ? size * 2 : 1000;
A = realloc(A, sizeof(*A) * size);
if (A == NULL) {
fprintf(stderr, "out of memory for %d items\n", size);
return 1;
}
}
if (sscanf(line, "%19[^,\n],%19[^,\n],%19[^,\n]%c",
A[len].SKU, A[len].Plant, A[len].Qty, &c) != 4
|| c != '\n') {
fprintf(stderr, "invalid format: %s\n, line);
} else {
len++;
}
}
fclose(stream);
//print matrix
for (i = 0; i < len; i++) {
printf("%s,%s,%s\n", A[i].SKU, A[i].Plant, A[i].Qty);
}
free(A);
}
return 0;
}
I'm trying to find the entropy of any given file. However, when I run my program, it always gives 3.00000 as an answer. I haven't used C in awhile, but I'm not sure where I'm going wrong here. I've been fiddling with it for a few hours now. Any tips would be great, thank you!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define SIZE 256
int entropy_calc(long byte_count[], int length)
{
float entropy;
float count;
int i;
/* entropy calculation */
for (i = 0; i < SIZE; i++)
{
if (byte_count[i] != 0)
{
count = (float) byte_count[i] / (float) length;
entropy += -count * log2f(count);
}
}
return entropy;
}
int main(int argc, char **argv)
{
FILE *inFile;
int i;
int j;
int n; // Bytes read by fread;
int length; // length of file
float count;
float entropy;
long byte_count[SIZE];
unsigned char buffer[1024];
/* do this for all files */
for(j = 1; j < argc; j++)
{
memset(byte_count, 0, sizeof(long) * SIZE);
inFile = fopen(argv[j], "rb"); // opens the file given on command line
if(inFile == NULL) // error-checking to see if file exists
{
printf("Files does not exist. `%s`\n", argv[j]);
continue;
}
/* Read the whole file in parts of 1024 */
while((n = fread(buffer, 1, 1024, inFile)) != 0)
{
/* Add the buffer to the byte_count */
for (i = 0; i < n; i++)
{
byte_count[(int) buffer[i]]++;
length++;
}
}
fclose(inFile);
float entropy = entropy_calc(byte_count, length);
printf("%02.5f \t%s\n", entropy, argv[j]);
}
return 0;
}
Your return type of the function entropy_calc() should be float not int.