Why do the functions get skipped over without being read? - c

Im trying to write code so that it will open a file (worker and benefits) and then display them when asked at the start. I can do this but I would like to use functions. When I run my program it ends as soon as it starts. How do I set up functions so that they will run.
Ive tried renaming the functions to no sucess. Ive also found no help throught Youtube tutorials.
#include <stdio.h>
#include <stdlib.h>
int ans;
char Benefits[150];
char Worker[150];
int readfile();
int end();
int welcome();
int main()
{
int welcome()
{
puts("Hi, Welcome to whatever this is!!\n");
}
int readfile()
{
FILE*fpointer;
fpointer = fopen("Worker.txt","r");
char Worker[150];
while(!feof(fpointer))
{
fgets(Worker, 150, fpointer);
}
FILE*fpointer1;
fpointer = fopen("Benefits.txt","r");
char Benefits[150];
while(!feof(fpointer))
{
fgets(Benefits, 150, fpointer1);
}
fclose(fpointer);
}
int menu(char Benefits)
{
{
printf("1 - For option 1\n");
printf("2 - For option 2\n");
printf("3 - For option 3\n");
printf("4 - For option 4\n");
printf("5 - exit\n");
scanf("%1d", &ans);
}
{
if (ans==1)
puts(Benefits);
if (ans==2)
puts(Worker);
if (ans==3)
puts("This is option3");
if (ans==4)
puts("This is option4");
}
}
return 0;
}
I expect the output to print either of the files or exit. As of now It skips functions and ends the program.

The functions should be outside the main function. In your main function you call the functions as required.
int main()
{
welcome();
readfile();
etc.
return 0;
}
To be really useful functions can take parameters. If you define readfile like this you declare a parameter called filename that contains the name of the file. You can
use this inside your function instead of writing the exact name of the file.
int readfile (char *filename)
{
...
fpointer = fopen(filename,"r");
...
}
Now in main you can use
int main()
{
welcome();
readfile("Workers.txt");
...
}
This is what makes functions useful. You can now reuse the function for another file
with a different name. This isn't a solution for you but I hope it helps, even if just with your understanding.

Related

C Programming - Using Parallel Arrays to enter Names, Exercise Marks and Compute Average of Exercise Marks and Display

I'm doing self-study on C Programming, and I have been recommended the following C Program by my colleagues to study further, where you can enter the Name and Age and it displays and uses Insert, Delete, Display, and Exit menu options.
I'm trying to convert it to my current study stream logic scenario where I need to enter the Name, Exercise Mark 1 (up to 3), and then it computes the Average and gets displayed while employing the Insert, Delete, Display, Update (updating the scores only, not the names), Delete and Exit.
Any guidance please on how to learn this code and understand the logic, and apply it to the 2nd scenario will be much appreciated.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
//using parallel arrays as fields in the list
typedef struct list{
char name[MAX][31];
int age[MAX];
int last;
}LIST;
LIST L;//L structure is global
void save();
void retrieve();
void makenull();
void insert(char n[31],int a);
void del(char n[31]);
void display();
int locate(char n[31]);
int isfull();
int isempty();
int menu();
int main(){
char nm[31];
int ag;
makenull();
retrieve();
while(1){
switch(menu()){
case 1: system("cls");printf("Insert Mode\n");
printf("Input Name: ");scanf("%s",nm);
printf("Input Age: ");scanf("%d",&ag);insert(nm,ag);break;
case 2: system("cls");printf("Delete Mode\n");
printf("Input Name: ");scanf("%s",nm);del(nm);break;
case 3: display();break;
case 4: save();exit(0);
default: printf("\n1-4 lang!\n");system("pause");
}
}
return 0;
}
void makenull(){
L.last = -1;
}
void insert(char n[31],int a){
if (isfull()){
printf("List is full.\n");
system("pause");
}
else {
L.last++;
strcpy(L.name[L.last],n);
L.age[L.last]=a;
}
}
void del(char n[31]){
int p;
if (isempty()){
printf("List is empty.\n");
system("pause");
}
else {
p=locate(n);
if (p==-1){
printf("Not found.\n");
system("pause");
}
else{
for(int i = p;i<L.last;i++){
strcpy(L.name[i],L.name[i+1]);
L.age[i]=L.age[i+1];
}
L.last--;
printf("Successful delete operation.\n");
system("pause");
}
}
}
void display(){
int i;
system("cls");
printf(" Name Age \n");
for(i=0;i<=L.last;i++)
printf("%d.) %s %d\n",i+1,L.name[i],L.age[i]);
system("pause");
}
int locate(char n[31]){
int i;
for (i=0;i<=L.last;i++)
if(strcmp(L.name[i],n)==0)
return i;
return -1;
}
int isfull(){
if (L.last==MAX-1)
return 1;
else
return 0;
}
int isempty(){
return(L.last==-1);
}
int menu(){
int op;
system("cls");
printf("MENU\n");
printf("1. Insert\n");
printf("2. Delete\n");
printf("3. Display\n");
printf("4. Exit\n");
printf("\nSelect(1-4): ");
scanf("%d",&op);
return(op);
}
void save(){
FILE *fp;
int i;
fp=fopen("Practice4.dbf","w+");
if (fp==NULL){
printf("File Error.\n");
system("pause");
}
else{
for (i=0;i<=L.last;i++)
fprintf(fp,"%s %d\n",L.name[i],L.age[i]);
}
fclose(fp);
}
void retrieve(){
FILE *fp;
char n[31];
int i,a;
fp=fopen("Practice4.dbf","r+");
if (fp==NULL){
printf("File Error.\n");
system("pause");
}
else {
while(!feof(fp)){
fscanf(fp,"%s %d\n",n,&a);
insert(n,a);
}
}
fclose(fp);
}
Your code isn't properly formatted and there are no comments. I can't give you a direct answer with some code in it, but summing up all my comments (and of course I deleted them), this is what I've to say:
Consider this scenario-
if your .dbf has more than MAX 50 elements, then your while (!feof(fp)) inside retrieve() will keep calling insert() and insert() will keep executing its if () { } block.
You should put something like while (!feof(fp) && L.last < MAX) to prevent that situation and you'll need to further modify your code in insert(). Another thing is, this code doesn't have any update() function and scores variable. You'll need to add scores in your struct as well as there must be scores fields in your .dbf.
Now, for a moment let's say everything else is good to go in your code, then you should follow these following steps:
Declare variables
char nameInput[31];
float ex_marks[3], sum = 0, avr = 0;
in main().
Add another case 5 in your switch () block inside main() and translate and convert the following pseudocode into C code:
Read name in nameInput
locate()
if found then
3.a for i = 0 to 2
Read marks in ex_marks[i]
sum = sum + ex_marks[i]
3.b Calculate avr = sum / 3
3.c Display name and avr
else
Display name is not in the list.
exit
Also read about why is while(!feof()) always wrong?

how to change the program to do the same task without the program crashing?

I have an assignment to produce a program that will compare students answer to the answer key, and display the incorrect answers. The program then produces a report of the students incorrect answers and his final grade. The Program must use arrays and functions.
Currently I am trying to code two functions one to read the students answer file and store it in an array and the other to read answer key file and store it in another array. Then the functions will return both arrays to the main function later to be sent to another function to compare their contents(not yet done).
My problem with this code after pressing F11 to compile and run, i get a blank execution screen and a notification saying that the program has stopped working.
If my code contains a mistake or my approach is incorrect please tell me how to fix it.
note: this is my first semester learning C programming.
Thank you.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
//Modules
char* readstudent()
{
FILE*s_ans;
int i,j;
static char arrs[20];
s_ans=fopen("trial2.txt","r");
if (s_ans == NULL)//check if file can be opened
{
printf("error student");
}
while(!feof(s_ans))
{
for(j=0;j<20;j++)
{
fscanf(s_ans,"%s",arrs[j]);
}
}
printf("ReadStudent\n");
for(i=0;i<20;i++)
{
printf("%d\t %s\n",i+1,arrs[i]);
}
return arrs;
}
char* readcorrect()
{
FILE*c_ans;
int x,i;
static char arrc[20];
c_ans=fopen("CorrectAnswers.txt","r");
if (c_ans == NULL)//check if file can be opened
{
printf("error correct");
}
while(!feof(c_ans))
{
for(x=0;x<20;x++)
{
fscanf(c_ans,"%s",arrc[x]);
}
}
printf("ReadCorrect\n");
for(i=0;i<20;i++)
{
printf("%d\t %s\n",i+1,arrc[i]);
}
return arrc;
}
//Main
int main()
{
int i,j,n,x;
char* as_ans=readstudent();
char* ac_ans=readcorrect();
printf("Main");
for(i=0;i<20;i++)
{
printf("%s",as_ans[i]);
}
return 0;
}

Why isn't my write method initialised?

I have been trying to write words that are given by the user in the command shell,but for some reason my program instantly quits after the read() function,so the text in main() :"in main2\n" is never even written. I have been trying to locate my problem for about an hour now and can't seem to find it.
# include <stdio.h>
void write_zin(const char* zin,int length_zin){
const char * runner =zin;
printf("out of loop\n");
while(runner!=(runner+length_zin)){
printf("%c",*runner);
runner++;
}
}
void read(char* zin,int NUMBER_LETTERS,int NUMBER_WORDS){
int i ;
char woord[NUMBER_LETTERS+1];
zin[0]='\0';
for(i =0;i<NUMBER_WORDS;i++){
printf("Give a word with %i letters\n",NUMBER_LETTERS);
scanf("%s",woord);
strcat(zin,woord);
strcat(zin,'\0');
}
strcat(zin,'\0');
}
int main(){
const int NUMBER_LETTERS = 5;
const int NUMBER_WORDS = 2;
char zin[(NUMBER_LETTERS+1)*NUMBER_WORDS];
printf("in main 1\n");
read(zin,NUMBER_LETTERS,NUMBER_WORDS);
printf("in main 2\n");
write_zin(zin,(NUMBER_LETTERS+1)*NUMBER_WORDS);
printf("in main3\n");
return 0;
}
There are a couple errors in your code:
Function void read(char* zin,int NUMBER_LETTERS,int NUMBER_WORDS)
If you concatenate words separated by '\0' you will end having just one string, because every string function will stop at the first '\0' and will not process further characters. So you cannot use strcat(zin,'\0');
If you want to mark the separation between strings use another special character as '\n' The final function will be:
void read(char* zin,int NUMBER_LETTERS,int NUMBER_WORDS){
int i ;
char woord[NUMBER_LETTERS+1];
for(i =0;i<NUMBER_WORDS;i++){
printf("Give a word with %i letters\n",NUMBER_LETTERS);
scanf("%s",woord);
strcat(zin,woord);
}
}
2. Function void write_zin(const char* zin,int length_zin)
You cannot ever change the condition of a loop inside a loop. That is what you are doing, because runner is always changing inside the loop, and in addition it is part of your condition.
while(runner!=(runner+length_zin)){
printf("%c",*runner);
runner++;
}
The final function is:
void write_zin(const char* zin,int length_zin){
const char * runner =zin;
printf("out of loop");
while(*runner){
printf("'%c'",*runner);
runner++;
}
}

libmp3lame encoding to char array slow

I am trying to encode pcm audio that i generated using "mplayer -ao pcm:nowaveheader" into mp3 with a c program. I don't want to write the mp3 to a file, I want to keep in in an array until i need to write it to a file, I wrote this, and it appears to work in a short .9 second test file, but it is very slow. What exactly is wrong?
#include <stdio.h>
#include <stdlib.h>
#include <lame/lame.h>
lame_global_flags *gfp;
int loopcount;
int inputSize;
FILE *fp=NULL;
FILE *fpo=NULL;
char *mp3buffer;
int mp3buffersize;
int countsize;
int x=0;
int y=0;
short *pcmbuffer;
short *lpcmbuffer;
short *rpcmbuffer;
int parse()
{
printf("loading PCM data...\n");
pcmbuffer=malloc(inputSize);
fread(pcmbuffer,2,(inputSize/2),fp);
printf("data in buffer\n");
printf("splitting left and right channels\n");
lpcmbuffer=malloc(inputSize/2);
countsize=((inputSize/4)-1);
while (x<=countsize)
{
lpcmbuffer[x]=pcmbuffer[x*2];
x++;
}
x=0;
rpcmbuffer=malloc(inputSize/2);
while (x<=countsize)
{
rpcmbuffer[x]=pcmbuffer[(x*2)+1];
x++;
}
x=0;
printf("starting lame\n");
gfp=lame_init();
lame_set_num_channels(gfp,2);
lame_set_in_samplerate(gfp,44100);
lame_set_brate(gfp,256);
lame_set_mode(gfp,1);
lame_set_quality(gfp,5);
if (lame_init_params(gfp)<0)
{
return 1;
}
}
encode()
{
x=0;
mp3buffersize=(1.25*countsize+7200);
mp3buffer=malloc(mp3buffersize);
while (x!=countsize)
{
lame_encode_buffer(gfp,lpcmbuffer,rpcmbuffer,x,mp3buffer,mp3buffersize);
x++;
y++;
if(y==1000)
{
printf("%d %d\n",countsize,x);
y=0;
}
}
x=0;
lame_encode_flush(gfp,mp3buffer,mp3buffersize);
fpo=fopen("test.mp3","w");
fwrite(mp3buffer,1,countsize,fpo);
}
decode()
{
}
bounty()
{
//the quicker picker upper
printf("closing files\n");
fclose(fpo);
fclose(fp);
printf("closing lame\n");
lame_close(gfp);
printf("freeing pcmbuffer\n");
free(pcmbuffer);
free(lpcmbuffer);
free(rpcmbuffer);
free(mp3buffer);
}
int main(int argc,char **argv)
{
loopcount=atoi(argv[1]);
fp=fopen(argv[2],"r");
if (fp==NULL)
{
printf("File Read Error\n");
return 0;
}
fseek(fp,0,SEEK_END);
inputSize=ftell(fp);
fseek(fp,0,SEEK_SET);
printf("detected a %d byte(s) file\n",inputSize);
printf("Proceeding with parsing and importing...\n");
if (parse()==1)
{
printf("lame init error\n");
}
printf("loopcount is %d\n",loopcount);
encode();
//the Quicker Picker Upper
bounty();
return 0;
}
Short answer, make this your encode function:
void encode()
{
mp3buffersize=(1.25*countsize+7200);
mp3buffer=malloc(mp3buffersize);
lame_encode_buffer(gfp, lpcmbuffer, rpcmbuffer, countsize, mp3buffer, mp3buffersize);
lame_encode_flush(gfp,mp3buffer,mp3buffersize);
fpo=fopen("test.mp3","w");
fwrite(mp3buffer,1,countsize,fpo);
}
I've never used lame, but, it looked like in your encode() function you were calling lame_encode_buffer() again and again, overwriting the result each time, and doing from 0 to countsize as the number of samples per channel (argument 4).
Other comments:
Why aren't you using lame_encode_buffer_interleaved()? Much of your parse() function is just undoing the existing interleaving of your file, seems like a waste.
IMO, the mass of global variables you're using are UGLY. Ideally your encode() would look more like: encode(lame_global_flags *gfp, const short * lpcmbuffer, const short * rpcmbuffer, const int countsize) this way it is clear from reading the parameter list the type of the variables, and that they must have come from/been set by the caller. const is nice to clarify that they're only for reading.
Finally, you really should have done some profiling, e.g. printing time differences between entry and exit of functions, to figure where your time sink was, and posted what you'd found. I ventured a guess looking at your loops, the encode() function had the only loop with any meat in it. I never ran your program, maybe I'm 100% wrong.

Coredump in selfmade arrayList

i'm current working on a homework assesment where i'm programming a program ment to stitch textfiles with a piece of an ascii image to create a complete image of all the pieces. The way i intended to write the code is having a while loop looking through a directory finding the parts and adding them to an array. However in my AddFile method(or when i call it to be precise) i get a coredump.. I just started working with c so i dont know if it is very obvious to some of you why i get a coredump or more complicated. Also, i originaly wrote the addFile method to use and accept int's instead of the FILE type, at that point it worked perfectly without any coredumps so i suspect (but hey i might be wrong) that it went wrong when i tried to implement it with the FILE type.
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int listSize;
int listCapacity;
FILE *fileStream;
}FileList;
void addFile(FileList* list, FILE file)
{
if((*list).listSize<(*list).listCapacity)
{
(*list).fileStream[(*list).listSize]=file;
(*list).listSize+=1;
}
else
{
FILE *tempArray = calloc((*list).listSize,sizeof(FILE));
for(int i=0; i<(*list).listSize; i++)
{
tempArray[i]=(*list).fileStream[i];
}
//Do something with array...
free((*list).fileStream);
(*list).listCapacity=((*list).listCapacity)*2;
(*list).fileStream=calloc((*list).listCapacity,sizeof(FILE));
for(int i=0; i<(*list).listSize; i++)
{
(*list).fileStream[i]=tempArray[i];
}
(*list).fileStream[(*list).listSize]=file;
(*list).listSize+=1;
free(tempArray);
}
}
int main()
{
FileList intList;
intList.listSize=0;
intList.listCapacity=1;
intList.fileStream=calloc(intList.listCapacity,sizeof(int));
int fileYcoord=0;
int fileXcoord=0;
while(1)
{
char fileName [100];
int fileNameLength=sprintf(fileName,"part_%02d-%02d",fileXcoord,fileYcoord);
FILE * pFile = fopen (fileName,"r");
if(pFile!=NULL)
{
printf("- ! found file: %s - name length : %d \n",fileName,fileNameLength);
addFile(&intList,*pFile);
fclose(pFile);
fileXcoord++;
}
else
{
if(fileXcoord!=0)
{
fileYcoord+=1;
fileXcoord=0;
}
else
{
break;
}
}
}
printf("size %d , %d",fileXcoord, fileYcoord);
free(intList.fileStream);
return 0;
}
The call to addFile() is dereferencing a FILE *, producing a value of type FILE. This is wrong, this is an opaque type and should always be handled by pointers.

Resources