knapsack problem data storage from table in a File C - c

I am trying to store data for Value, Weight and Cost from a file containing a table which contains three columns of numbers for Value, Weight and Cost. The table may vary in length (9 or 21 rows) depending on the file chosen by the user.
I am having trouble trying to store the data from this file to use in a brute force function to solve the problem.
This is what I have so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int nr_rows;
int i = 1;
int j = 2;
int k = 3;
int l,m,n = 0;
int budget_cost;
int weight_lim;
char file_name[50];
float c[nr_rows][3];
char stringA[20] = "objectsA.txt";
char stringB[20] = "objectsB.txt";
printf("Enter the filename containing item listing: ");
scanf("%s", &file_name);
if(strcmp(file_name,stringA)==0)
{
nr_rows = 9;
}
else if(strcmp(file_name,stringB)==0)
{
nr_rows = 21;
}
printf("The number of rows is %d", nr_rows);
float value[nr_rows], weight[nr_rows], price[nr_rows];
FILE *fpointer;
fpointer = fopen(file_name, "r");
if(!fpointer)
{
printf("The file %s could not be opened.", file_name);
return 1;
}
j=0;
while(j<nr_rows)
{
i=0; // Skip the first line
while(i<3)
{
fscanf(fpointer, "%f", &c[j][i]);
//printf("%.0f\n", c[j][i]);
if(i=1) /* Change this if statement so that 1 ,4 ,7 ,10
etc. activates*/
{
c[j][i] = v[l];
l++;
printf("%f", v[l]);
}
else if(i=2)/* Change this if statement so that 2,5,8 etc.
activates*/
{
c[j][i] = w[m];
m++;
}
else if(i=3)/* Change this if statement so that 3,6,9 etc.
activates*/
{
c[j][i] = p[n];
n++;
}
i++;
}
j++;
}
fclose(fpointer);

//1. Read carefully your file name by doing:
scanf("%s", file_name); // instead of scanf("%s", &file_name);
//2. Declare c[nr_rows][3] only after reading "nr_rows"
//3. The main "while" loop could look like this
while(j < nr_rows)
{
fscanf(fpointer, "%f %f %f", &c[j][0], &c[j][1], &c[j][2]);
}
// Then,
fclose(fpointer);

Related

C Programming - Generating Random Numbers into a new text File and retrieving them to count the occurrences (then do statistics on the side)

My goal is to generate random numbers into a new txt file where I can retrieve the randomly generated values and count the occurrences of the values (e.g. Number 1 has appeared "x" number of times). My expected output should display an output like the example given and all the occurrences should add up to 600. There is an underline on the last bracket in my newfile() function. Thanks in advance.
First 10 lines of txt output file...
2
5
4
2
6
2
5
1
4
2
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int newfile(FILE *fp)
{
char fname[20];
printf("\nEnter the name of the file... ");
scanf("%19s",fname);//File name cannot have spaces
strcat(fname, ".txt");
fp=fopen(fname, "w");
int i, N = 600, newfile[N];
for(i=0;i<N;i++)
{
newfile[i]= ((rand() % 6)+1);
fprintf(fp,"%d\n",newfile[i]);
}
}
int main()
{
int i = 0;
FILE *fp;
do
{
newfile(fp);
i++;
}
while (i<1);
FILE* fpointer;
char filename[20];
int value = 0, result = 0, num[600] = { 0 };
float sum, mean;
printf("\nEnter the name of the file... ");
scanf("%19s",filename);
fpointer = fopen(filename, "r");
if (fpointer == NULL) {
printf("ERROR: CANNOT OPEN FILE!\n");
return -1;
}
result = fscanf(fpointer, "%d", &value);
while (result == 1)
{
{
num[value] = num[value] + 1; // num[value]++
}
result = fscanf(fpointer, "%d", &value);
}
for (int i = 0; i <= 6; i++) {
if (num[i] > 0) {
printf("Number %i has appeared %d times\n", i, num[i]);
}
}
sum = (1*(num[1])+2*(num[2])+3*(num[3])+4*(num[4])+5*(num[5])+6*(num[6]));
mean = sum / 600;
printf("\nThe mean is %f",mean);
fclose(fpointer);
return 0;
}
The main problem in your code is that you forgot to close the file inside newfile function.
So just add fclose(fp); at the end of the function.
Minor issues:
you don't need to pass fp to the function newfile. Just use a local variable.
newfile[N] is not needed at all. Simply do: fprintf(fp,"%d\n", (rand() % 6)+1);
num[600] = { 0 }; is much too large as you only use index 0 .. 6
Before doing num[value] = ... you should check that value is in the expected range, i.e. to avoid writing out of bounds.

C - Read the array from the file and display the amount of introduced lines on the screen

Im trying to make a program do write to a file and read from it. The problem is when i open the file to read only and show the data in it, it does not show me all lines. If i insert a bigger number of lines it will show random input.
for (i = 0; i < stud2[i].k; ++i)
{
printf("Name: %s\tHeight: %d\n", stud2[i].name, stud2[i].height);
}
If i change the variable stud2[i].k to 100 it will show me random data input.
I tried to add the variable k to the struct so it can save how many times i run the software and then tried to add it to stud2[i].k but i cant get it working.
How can i make it only show the number of executions and not random lines of data input? Thank you
Heres the code:
#include <stdio.h>
#include <stdlib.h>
struct student
{
char name[50];
int height;
int k;
};
int main()
{
struct student stud1[100], stud2[100];
FILE *fptr;
int i, x;
printf("How many do you want to add?");
scanf("%d", &x);
fptr = fopen("study.txt", "ab+");
for (i = 0; i < x; ++i)
{
fflush(stdin);
stud1[i].k = stud1[i].k + x;
printf("Enter name: ");
gets(stud1[i].name);
printf("Enter height: ");
scanf("%d", &stud1[i].height);
}
fwrite(stud1, sizeof(stud1), 1, fptr);
fclose(fptr);
fptr = fopen("study.txt", "rb");
fread(stud2, sizeof(stud2), 1, fptr);
for (i = 0; i < stud2[i].k; ++i)
{
printf("Name: %s\tHeight: %d\n", stud2[i].name, stud2[i].height);
}
fclose(fptr);
}

Can't initialize my array counter in C despite trying everything

I've been working on this school assignment which creates a restaurant menu, and I have an array to store everything that a person orders. The array that stores the orders ordered is array OrderedItems [30]. This array is basically a counter. When a person orders order number 1 as an example OrderItems[1] increases by 1.
I've tried to initialize by using OrderedItems [30] = {0}, and using a for loop to initialize every spot individually, However, that didn't work. Please help me initialize this array. I've also tried memset(OrderedItems, 0, 30); and this didn't work too so I really have no clue what to do.
I also want to add that I've tried to globally declare the OrderedItems array since I've heard that all global declarations are automatically initialized to 0, but that also didn't work.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
FILE *fPointer1; //for food//
FILE *fPointer2; //for invoice//
int count;
char name[50];
float price;
void FunctionToPrintFoodItems (void)
{
fPointer1 = fopen ("Food.txt", "a+");
float price;
printf("ITEMCODE\tDESCIPTION\tPRICE (RM)\n");
while (!feof (fPointer1))
{
fscanf(fPointer1, "%d %s %f", &count, name, &price);
printf("%d\t\t%s\t\t%.2f\n", count, name, price);
}
fclose (fPointer1);
}
void clrscr()
{
system("#cls||clear"); //might not need. Will delete it not needed//
}
void debug (void)
{
printf("THIS IS PRINTED");
}
#define clear clrscr ();
#define printfood FunctionToPrintFoodItems();
#define de debug();
int main ()
{
fPointer1 = fopen("Food.txt", "w");
fprintf(fPointer1, "1 BigM 10.40\n");
fprintf(fPointer1, "2 Cheeseburger 9.45");
fclose (fPointer1);
int i;
int MainMenuCode;
int additems = 0;
int orderitems;
int item;
int ordered;
int OrderedItems[30] = {0};
memset(OrderedItems, 0, 30);
for (i=0 ; i < 30 ; i++)
{
OrderedItems[i] = NULL;
printf("%d: %d\n", i, OrderedItems);
}
do
{
printf("WELCOME TO RESTOURANT MAC C - Main Menu\n\n");
printf("[1] Add new food items\n\n");
printf("[2] Take order\n\n");
printf("Enter ITEM CODE (0 to Quit) : ");
scanf("%d", &MainMenuCode);
if (MainMenuCode == 1)
{
clear;
additems = 1;
printf("WELCOME TO RESTAURANT MAC C - Add Menu\n\n");
printfood;
printf("\n");
while ( additems == 1 )
{
printf("Enter description (0 to Main Menu) : ");
scanf("%s", name);
if (strcmp (name, "0") == 0)
{
additems = 0;
clear;
break;
}
printf("Enter price (RM) : ");
scanf("%f", &price);
count ++;
fPointer1 = fopen ("Food.txt", "a");
printf("\n%d\t\t%s\t\t%.2f\n\n", count, name, price);
fprintf(fPointer1, "\n%d %s %.2f", count, name, price);
fclose (fPointer1);
}
}
else if (MainMenuCode == 2)
{
clear;
orderitems = 1;
printf("WELCOME TO RESTAURANT MAC C- Take Order\n\n");
printfood;
while (orderitems == 1)
{
fPointer1 = fopen ("Food.txt", "a+");
printf("Enter ITEM CODE (0 to Quit, 100 for Main Menu) : ");
scanf("%d", &item);
if (item == 100) break;
else if (item == 0) //final approach//
{
fPointer2 = fopen ("Invoice.txt", "a+");
de;
fclose (fPointer2);
return 0;
}
else if (item == 900)
{
for (i=0 ; i < 30 ; i++)
printf("%d: %d\n", i, OrderedItems);
}
else if (item > count || item < 1)
{
printf("\n\nITEM CODE not available. Try again\n\n");
}
else
{
OrderedItems[item]++;
printf("%d %d", item, OrderedItems);
}
fclose (fPointer1);
}
}
else printf("Please enter a valid Menu Code\n");
} while (MainMenuCode != 0);
return 0;
}
- printf("%d: %d\n", i, OrderedItems);
+ printf("%d: %d\n", i, OrderedItems[i]);
OrderedItems is an address of the array's first element.
OrderedItems[0] is a value of the array's first element.
OrderedItems[i] is a value of the array's i-th element.
The call to memset should specify how many bytes to set. You need to tell it the size of the type to initialise.
memset(OrderedItems, 0, 30 * sizeof(int))

Stack around the variable was corrupted with pointer arithmetics

With the code below, I'd always run into "Stack around the variable 'UserCode' was corrupted.
If I'm not mistaken, when I do userCode = (char*)malloc(sizeof(char)*N);, shouldn't it create an "array" with size of char*n ? I'm guessing my issue is either with my declaration of an array, or my pointer arithmetic.
Any help would be highly appreciated.
#include "stdafx.h"
#include <math.h>
int userPrompt1() {
int numOfAlphabets = 0;
printf("Please enter a number from 1 to 8 to choose how many alphabets you want\n");
scanf_s(" %d", &numOfAlphabets);
if (numOfAlphabets > 8 || numOfAlphabets < 0) {
printf("Sorry! Invalid number entered. Try again. \n");
numOfAlphabets = userPrompt1();
}
return numOfAlphabets;
}
int userPrompt2() {
int numOfLetters = 0;
printf("Please enter the number of letters you want to guess\n");
scanf_s(" %d", &numOfLetters);
if (numOfLetters < 0) {
printf("Sorry! Invalid number entered. Try again. \n");
numOfLetters = userPrompt2;
}
return numOfLetters;
}
int tryCalculator(int K, int N) {
int tries = 0;
tries = 1 + ceil(N * log2(K));
return tries;
}
void codeGenerator(char codeGuessIn[], char letters[], int size) {
for (int i = 0; i < size; i++) {
int rando = rand() % size;
codeGuessIn[i] = letters[rando];
printf(" %c", codeGuessIn[i]);
}
printf("\n");
}
void codeChecker(char codeGuessIn[], char generatedCode[], int size) {
int correctAlphabets = 0;
for (int i = 0; i < size; i++) {
if (codeGuessIn[i] == generatedCode[i]) {
correctAlphabets++;
}
}
printf(" %d in correct place \n", correctAlphabets);
}
void getUserCode(int size, char *userCode[]) {
for (int i = 0; i < size; i++) {
printf("Please enter letter #%d \n", i+1);
getchar();
scanf_s(" %c", &userCode[i]);
}
}
int main(void)
{
char letters[8] = { 'A','B','C','D','E','F','G','H' };
char *generatedCode; //array to hold generated code
char *userCode; // array to hold generated code.
int K = userPrompt1(); //how many different alphabets in code
int N = userPrompt2(); //how many letters in code
int tries = tryCalculator(K, N);
//int gameEnd = 1;
userCode = (char*)malloc(sizeof(char)*N);
generatedCode = (char*)malloc(sizeof(char)*N);
codeGenerator(generatedCode, letters, N);
getUserCode(N, &userCode);
//codeChecker(userCode, generatedCode, N);
return 0;
}
void getUserCode(int size, char *userCode[]) {
scanf_s(" %c", &userCode[i]);
Here, userCode[i] is a char * (pointer-to-char), &userCode[i] is a char ** (pointer-to-pointer-to-char), and scanf("%c") expects a char *. A good compiler would warn about that.
I think what you meant to do here is something like:
void getUserCode(int size, char *userCode) {
scanf_s(" %c", &userCode[i]);
}
int main(void) {
char *userCode = malloc(N);
getUserCode(N, userCode);
}
The printf(), getchar(), scanf() combination here reeks of the bad habits created by scanf: you're discarding the first character entered by the user because you're relying on an extra character in the input buffer.
See http://c-faq.com/stdio/scanfprobs.html and read full lines of input with fgets() instead of using scanf().
Also,
int userPrompt2() {
int numOfLetters = 0;
...
numOfLetters = userPrompt2;
}
You're assigning a function pointer to an int. (A normal compiler should warn about this.) If the idea here is to call the function again to repeat the prompt in case the user enters something silly, it's probably a better idea to use a loop instead of a recursive call anyway.

C asking for user txt file, saving in array, and outputting in txt

So I have a function built already that calculated 25 random temperatures and outputted them and had a max, min, and average feature. I'm now trying to incorporate input files and output files via txt.
I tried to do some research and plug in what I could (even if I barely understood it), can someone lend some light on my code?
int get_value(void);
void calc_results(void);
void read_temps(void);
int sum = 0;
int min = 0;
int max = 0;
int temp[25];
int i = 0; //For array loop
int j = 0; //For printf loop
float avg = 0;
void read_temps() {
char fname[128];
printf("Enter .txt file name \n");
scanf("%123s", fname);
strcat(fname, ".txt");
FILE *inputf;
inputf=fopen(fname, "w");
for (i = 0; i < 25; i++){
temp[i] = fname;
sum += temp[i];
}
}
int main () {
calc_results();
return 0;
};
void calc_results(void) {
FILE * fp;
fp = fopen("Output_temps.txt", "w+");
avg = ((sum)/(25));
max = temp[0];
for(i=1;i<25;i++){
if(max<temp[i])
max=temp[i];
};
min =temp[0];
for(i=1;i<25;i++){
if(min>temp[i])
min=temp[i];
};
fprintf("Temperature Conditions on October 9, 2015 : \n");
fprintf("Time of day Temperature in degrees F \n");
for(j=0;j<25;j++){
fprintf(" %d %d\n",j,temp[j]);
}
fprintf("Maximum Temperature for the day: %d Degrees F\n", max);
fprintf("Minimum Temperature for the day: %d Degrees F\n", min);
fprintf("Average Temperature for the day: %.1f Degrees F\n", avg);
fclose(fp);
};
There were a few errors in your code, the most critical one being it doesn't compile. If you're having issues you'll want to follow the instructions for how to make a ssce. You will get a much better response this way. Then explain clearly the specific issue you are having and what it is that is happening or not happening as opposed to what you expect.
With your code you seem to be assigning to your temp array the fname variable instead of reading in the int data from the user file.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// assuming you want a maximum of temperatures of 25
#define TEMP_NUMBER 25
// use a struct to maintain and the temparatur data in one place
// without resorting to using global variables or having functions
// that require numerous parameters.
struct temp_data {
char fname[128];
int max;
int min;
int sum;
int temps[TEMP_NUMBER];
float avg;
};
struct temp_data *temps_init(void)
{
// creates a pointer to struct temp_data to hold
// your various temparture related fields
struct temp_data *td = malloc(sizeof *td);
td->sum = 0;
td->avg = 0.0;
return td;
}
void read_temps(struct temp_data *td)
{
// in your sample code you have this set to "w", needs to be "r"
FILE *inputf = fopen(td->fname, "r");
// handle error
if (!inputf) {
perror("fopen");
exit(0);
}
for (int i = 0; i < TEMP_NUMBER; i++) {
// you were setting fname to the temparature array
// instead you need to scan the temp file
fscanf(inputf, "%d", &(td->temps[i]));
td->sum += td->temps[i];
}
}
void print_results(struct temp_data *td)
{
// a print function to separate logic
FILE *fp = fopen("Output_temps.txt", "w+");
if (!fp) {
perror("fopen");
exit(0);
}
fprintf(fp, "Temperature Conditions on October 9, 2015 : \n");
fprintf(fp, "Time of day Temperature in degrees F \n");
for(int i=0; i < TEMP_NUMBER; i++)
fprintf(fp, " %d %d\n", i, td->temps[i]);
fprintf(fp, "Maximum Temperature for the day: %d Degrees F\n", td->max);
fprintf(fp, "Minimum Temperature for the day: %d Degrees F\n", td->min);
fprintf(fp, "Average Temperature for the day: %.1f Degrees F\n", td->avg);
fclose(fp);
}
void calc_results(struct temp_data *td)
{
// do only calculations
td->avg = td->sum / TEMP_NUMBER;
td->min = td->temps[0];
td->max = td->temps[0];
for (int i=1; i < TEMP_NUMBER; i++) {
td->min = td->temps[i] < td->min ? td->temps[i] : td->min;
td->max = td->temps[i] > td->max ? td->temps[i] : td->max;
}
}
int main(int argc, char *argv[])
{
// Moved user input into the main() from read_temps()
// now read_temps() only needs to read and record the temp data
struct temp_data *td = temps_init();
printf("Enter .txt file name \n");
scanf("%123s", td->fname);
strcat(td->fname, ".txt");
read_temps(td);
calc_results(td);
print_results(td);
free(td);
return 0;
};
Using a file called sample.txt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

Resources