How to optimize the code to avoid a time limit error - c

I'm creating a prog for my exam. The code works properly but i got Time Limit error. How I can write this code bettere to avoid this error?
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
int a, sum;
float b, i;
i=0;
sum=0;
FILE *file1;
file1=fopen("input.txt","w");
do{
fscanf(file1, "%d", &a);
if(a!=0){
sum=sum+a;
i++;
}
} while(a!=0);
fclose(file1);
b=(sum/i);
printf("%f", b);
FILE *file2;
file2=fopen("output.txt","w");
fprintf(file2, "%f", b);
fclose(file2);
return 0;
}

This code is a potential problem:
do{
fscanf(file1, "%d", &a);
if(a!=0){
sum=sum+a;
i++;
}
} while(a!=0);
You don't check the return value from fscanf(), so when you hit the end of the input file, if the last value you read is non-zero, your code will go into an infinite loop.
A better solution:
do{
int numScanned = fscanf(file1, "%d", &a);
// break loop if fscanf() fails for any reason
if ( numScanned != 1 ) break;
if(a!=0){
sum=sum+a;
i++;
}
} while(a!=0);

You can remove fscanf(file1, "%d", &a); from do while there is no use of it because you are opening input.txt file in "w" mode so it will truncate and considered as new empty file. so, it don't have any content inside it. this way time complexity will be reduced.

Related

How to stop inserting values by input?

If the user has to insert a number of values and then they want to stop how can I do?
For example the user has to insert float values but if they insert a letter the loop stops. How can I create something like this:
for(;;){
scanf("%f", &n);
if(!isdigit(n))
break;
}
scanf is a poor choice for interactive user input. Especially because if the user types something that scanf does not expect, that input stays in the internal input buffer and will most likely cause trouble in the following scanfs further in the program.
I'd go for something like this:
#include <stdio.h>
int main(int argc, char * argv[])
{
float n;
char input[100];
for (;;) {
fgets(input, sizeof(input), stdin);
if (sscanf(input, "%f", &n) != 1)
break;
printf("User input = %f\n", n);
}
printf("Last line entered by user: %s", input);
}
You can use scanf return value to break the loop.
Example:
for(;;){
if(scanf("%f", &n) != 1)
break;
}
scanf will return 1 if it successfully read the float.
Give a try with this code... I think it will work fine:
#include <stdio.h>
int main() {
float n;
int check = 0;
for( ;; ) {
check = scanf("%f", &n);
if (check != 1) break;
printf("%f\n ", n);
}
return 0;
}
You can use this very simple syntax, if you are expecting query type inputs where there's no need to remember the values
float n;
while(scanf("%f",&n)){
printf(" %f",n);
}
This will break on a character input.
If you need more precautions use Jabberwocky's answer.

C read file lines and print them

I want to read a .dat file whose first line consists of a float and all consecutive lines are "int * int" or "int / int" and print or return whether the float is a result each division or multiplication.
I am very unpleased with the results that I am getting. My experience is limited to only a couple of hours doing C. Therefore I have no idea what is missing for the program to do what the code is looking like it would do.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int countlines(FILE* f){
int nLines = -1;
char xLine[10];
while(fgets(xLine,10,f)!=NULL){
nLines+=1;
}
return nLines;
}
int main(){
FILE * fPointer = fopen("test.dat", "r");
float dpFloat;
char oprnd[10];
int frstInt;
int scndInt;
//get float from first line
fscanf(fPointer, "%f", &dpFloat);
//count amount of lines below float
int amtLines = countlines(fPointer);
//loop through the other lines and get
int i;
for (i = 0; i < amtLines; i++){
fscanf(fPointer, "%d %s %d", &frstInt, oprnd, &scndInt);
//checking what has been read
printf("%d. %d %s %d\n", i, frstInt, oprnd, scndInt);
//print 1 if firstline float is quot/prod of consecutive line/s
//else 0
if (strcmp(oprnd,"*") ==1) printf("%i\n", (frstInt*scndInt)==dpFloat);
if (strcmp(oprnd,"/") ==1) printf("%i\n", (frstInt/scndInt)==dpFloat);
}
fclose(fPointer);
return 0;
}
Problem 1: strcmp returns 0 when its arguments are equal, not 1.
Problem 2: frstInt/scndInt will truncate the result. Fix it by adding 1.0* to the expression.
The lines
if (strcmp(oprnd,"*") ==1) printf("%i\n", (frstInt*scndInt)==dpFloat);
if (strcmp(oprnd,"/") ==1) printf("%i\n", (frstInt/scndInt)==dpFloat);
need to be
if (strcmp(oprnd,"*") == 0) printf("%i\n", (frstInt*scndInt)==dpFloat);
if (strcmp(oprnd,"/") == 0) printf("%i\n", (1.0*frstInt/scndInt)==dpFloat);
// ^^^ ^^^
Please be aware of the pitfalls of comparing floating point numbers. It's best to compare them within a tolerance. See Comparing floating point numbers in C for some helpful tips.

C - Loop, <math.h>, and float

#include <stdio.h>
#include <math.h>
int main()
{
int i;
int result;
float f;
while((result = scanf("%d", &i)) != EOF)
{
scanf("%f", &f);
printf("%.0f %.0f %.0f\n", floor(f), round(f), ceil(f));
}
printf("Done.\n");
return 0;
}
Hi,
I just began with C and I'm having a problem solving a question.
The problem is that with the user input, I need to get three sets of numbers that are floored, rounded, and ceiled. This process must be ongoing until the user stops by EOF command (Ctrl-D).
When I run my code above, input a value 3.1415, I get 0 0 1 as an output, which is wrong because it's supposed to be 3 3 4.
Any suggestions or help on how to fix the problem would be appreciated.
According to your code, you first need to input an integer value and then enter a float value.
OR, you can start accepting float value like this:
#include <stdio.h>
#include <math.h>
int main()
{
int result;
float f;
while((result = scanf("%f", &f)) != EOF)
{
printf("%.0f %.0f %.0f\n", floor(f), round(f), ceil(f));
}
printf("Done.\n");
return 0;
}
According to your code you need to input integer first then float, But if you enter float value first, that value read by i first and return 0 that is !=EOF, so second scanf does not wait for input, because it is inside the while loop. So always you will get 0 0 1 for all inputs!
To scan a number inside while loop use-
if (scanf("%f", &f) == 0) {
printf("Err. . .\n");
do {
c = getchar();
}
while (!isdigit(c));
ungetc(c, stdin);
Else scan float value first instead of int and float. Try this code-
while((result = scanf("%f", &f)) != EOF)
{
printf("%.0f %.0f %.0f\n", floor(f), round(f), ceil(f));
}
printf("Done.\n");

read single-precision use double precision variable in C

I have a text file containing single precision data, such as
0.123456 0.123456 0.123456
I want to read it in C using following syntax:
FILE *myfile.
double c[4];
int i=0;
c[0]=1;
myfile=fopen(...)
for (i=1;i<=3;i++) {
fscanf(myfile, "%lf", &c[i]);
}
What I print is a huge number that is obviously wrong.
Any one can solve this problem?
Ps: I have edited my problems after I viewed the answers.
here is my more information:
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
FILE *file_params;
int main() {
double *delx;
int i;
file_params=fopen(filename,"r");
delx = (double *) malloc ((4)*sizeof(double));
delx[0]=0;
for(i=1; i<=3; i++) fscanf(file_params, "%lf", &delx[i]);
for(i=1; i<=3; i++) printf("%lf", delx[i]);
return 0;
}
Responding to the version of code that appears as I write ...
Remove #include <windows.h>
Change filename to be the name of a file that exists
Check that file_params != NULL and delx != NULL before proceeding
Check the return value of fscanf, e.g. if ( 1 != fscanf(file_params, "%lf", &delx[i]) ) { printf("fscanf failed\n"); exit(EXIT_FAILURE); }
Change printf("%lf", to printf("%f ",
Program works.
What I print is a huge number that is obviously wrong.
Possibly you are seeing the numbers all next to each other without spaces (since you didn't printf a space) and didn't realize what you were seeing.
Array indexes start at 0. You started at 1.
for loop should be
for (i=0;i<3;i++)
fscanf(myfile,"%lf",&c[i]);
I see the following errors:
Use %lf instead of lf%.
Use &c[i] instead of &c.
In the for- loop, use,
for (i=0;i<3;i++) {
instead of
for (i=1;i<=3;i++) {
In summary,
for (i=0;i<3;i++) {
fscanf(myfile, "%lf", &c[i]);
}

Fill a matrix from a file in C

I'm trying to write a little program that read from a file. I tryied this codes from a file (random.dat) that contains the following numbers:
0.575 0.235
0.456 0.322
The code that I wrote is the following:
#include <stdio.h>
#include <stdlib.h>
#define N 2
int main (void) {
FILE *fp;
int i, j;
double x,y,data[N][N] = {{0}};
if ((fp = fopen("random.dat", "r")) == NULL ) {
printf("Error\n");
exit(EXIT_FAILURE);
}
fp = fopen("random.dat","r");
printf("\n");
for (i=0;i<N;i++){
fscanf(fp,"%lf",&x);
for(j=0;j<N;j++){
fscanf(fp,"%lf",&x);
data[i][j] = x;
printf("data[%d][%d]=%lf\n",i,j,data[i][j]);
}
}
printf("\n");
fclose(fp);
return(0);
}
Does the code is well written?
I don't understand why the terminal write:
data[0][0]=0.235000
data[0][1]=0.465000
data[1][0]=0.322000
data[1][1]=0.322000
Instead of:
data[0][0]=0.575000
data[0][1]=0.235000
data[1][0]=0.465000
data[1][1]=0.322000
Any idea? Thanks!
In this nested loop (reformatted to be easier to read):
for (i=0; i<N; i++)
{
fscanf(fp, "%lf", &x); // first fscanf
for(j=0; j<N; j++)
{
fscanf(fp, "%lf", &x); // second fscanf
data[i][j] = x;
printf("data[%d][%d]=%lf\n", i, j, data[i][j]);
}
}
You'll see that the inner loop immediately overwrites the x value read in your outer loop. That means you essentially skip reading the first number in the file entirely. Later that causes one of the inner-loop fscanf calls to fail, but since you don't check the return value, your program doesn't notice.
Just delete the first fscanf() line and you'll be set.
As an editorial aside, if you step through your program with a debugger, you'd see this problem happening immediately.
replace statements,
for (i=0;i<N;i++){
fscanf(fp,"%lf",&x);
for(j=0;j<N;j++){
fscanf(fp,"%lf",&x);
data[i][j] = x;
printf("data[%d][%d]=%lf\n",i,j,data[i][j]);
}
}
with
for (i=0;i<N;i++){
for(j=0;j<N;j++){
fscanf(fp,"%lf",&x);
data[i][j] = x;
printf("data[%d][%d]=%lf\n",i,j,data[i][j]);
}
}

Resources