Have made a program that reads a .csv file and stores the highest number in another file. The problem is that my program can't read comma separated numbers like 1,5,6,7,1,2. Here is the loop I need help to change
int i;
int max = 0;
int min = 0;
while (!feof(fp))
{
fscanf( fp, "%d", &i);
if (i < min)
min = i;
if (i > max)
max = i;
}
And this is what I print out:
fprintf(q,"%d",max);
printf("maximum value is %d \n", max);
fclose(q);
fclose(fp);
#include <stdio.h>
#include <limits.h>
int main(void){
FILE *fp = fopen("input.csv", "r");
FILE *q = fopen("max.txt" , "w");
int i;
int max = INT_MIN;
int min = INT_MAX;
while(1){
int state = fscanf(fp, "%d", &i);
if(state == 1){
if (i < min)
min = i;
if (i > max)
max = i;
} else if(state == EOF){
break;
} else {
char ch;
fscanf(fp, " %c", &ch);
if(ch != ','){
fprintf(stderr, "\nformat error\n");
break;
}
}
}
fprintf(q, "%d", max);
printf("maximum value is %d\n", max);
fclose(q);
fclose(fp);
return 0;
}
Related
I am trying to read a text file, character by character, with fgetc() function but it does not show any output. It is a school project and it is still in very very simple way just to test the functionality of the program.
#include <stdio.h>
#include <stdlib.h>
void fn1(FILE *f);
void fn9(FILE *fp, char, char);
int main() {
FILE *fp = fopen("text.txt", "r");
if (fp == NULL) {
perror("Error: ");
exit(1);
}
fn1(fp);
fn9(fp, '0', '9');
fclose(fp);
return 0;
}
void fn1(FILE *f) {
int num, sum = 0, count = 0;
while (fscanf(f, "%d", &num) == 1) {
if (num > 0) {
sum += num;
count++;
}
}
printf("the avg of positive nums is %.2f", (float) sum / count);
}
void fn9(FILE *fp, char m, char n) {
int ch;
int count1 = 0, count2 = 0;
while ((ch = fgetc(fp)) != EOF) {
if (ch == m)
count1++;
if (ch == n)
count2++;
printf("%c", ch);
if (ferror(fp))
break;
}
printf("\n%c is seen %d times", m, count1);
printf("\n%c is seen %d times", n, count2);
fclose(fp);
}
The file's content that I test is:
90
16
-34
100
After fn(fp) return, fp will point to the last location in the file. It needs to be reset to the start of file before fn9 is called. Use fseek to point fp to the start of file and it should work :)
I tried to read a file containing an empty box of '*', the error message doesn't get printed, so the file is opened, but the scan doesn't work. I tried to print the count variable, and the value of count is 0. I don't really know where the fault is. Please help... Thanks
the file content that I want to read
int openmap(int file_no){
char filename[32];
char mapp[100][100];
int number;
int count;
int x[100];
int nomor = 1;
for(int i = 1; i <= file_no; i++){
sprintf(filename, "map%d.txt", i);
FILE *test = fopen(filename,"r");
if(test)
{
printf("%2d. Map %d\n", nomor, i);
x[nomor-1] = i;
nomor++;
fclose(test);
}else if(!test && i > file_no){
printf("No map available!");
return 1;
}
}
do{
printf("[0 to cancel] [1 - %d]>> ", nomor-1);
scanf("%d", &number);
}while(number < 0 || number > file_no);
if(number > 0){
sprintf(filename,"map%d.txt", x[number-1]);
printf("%s", filename);
FILE *open = fopen(filename, "r");
if(!open){
printf("error");
}
while(!feof){
fscanf(open, "%[^\n]\n", mapp[count]);
count++;
}
fclose(open);
for(int i = 0; i < count ; i++){
printf("%s\n", mapp[i]);
}
}
}
I created a small test program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main () {
char mapp[100][100];
int i, count = 0;
char filename[32];
sprintf(filename, "test.txt");
FILE *open = fopen(filename, "r");
if(!open){
printf("error");
}
while(!feof(open)){
fscanf(open, "%[^\n]\n", mapp[count]);
count++;
}
fclose(open);
for(i = 0; i < count ; i++){
printf("%s\n", mapp[i]);
}
}
as far as i can see the only issue you have regarding the relevant section is your while loop condition, you should use: while(!feof(open)) - i tested my solution and it works so it seems that this is the only issue in your solution
Totals different for same file when executed.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_FILE_NAME 100
#define RUNS 1
int main() {
int num,i;
FILE *fp;
char*s, buf[1024];
int count =0;
char c;
char filename[MAX_FILE_NAME];
printf("Enter filename: ");
scanf ("%s",filename);
if ((fp =fopen(filename, "r")) == NULL) {
printf("Error");
exit(1);
}
fscanf(fp,"%d",&num);
for (c = getc(fp); c!= EOF; c = getc(fp))
{
if (c == '\n'){
count = count+1;
}
}
printf("%s has %d numbers \n", filename, count);
int f;
printf("Choose from the options how many processes you want to use [1,2,4]: ");
scanf("%i", &f);
printf("%i processes \n", f);
int fds[f+1][2];
int numb[count];
int x,k;
time_t start, finish;
start = time(NULL);
for(i = 0; i < RUNS; i++)
{
pipe(fds[f]);
for( x = 0; x<f; x++)
{
pipe(fds[x]);
int ind[2];
ind[0] = ((x)*(count/f));
ind[1] = ((x+1)*(count/f));
write(fds[x][1], &ind, 2* sizeof(int));
if (fork() ==0)
{
int t =0;
int ind2[2];
read(fds[x][0], &ind2, 2*sizeof(int));
for( k = ind2[0]; k<ind2[1]; k++)
{
t += numb[k];
}
write(fds[f][1], &t, sizeof(int));
exit(0);
}
}
int m, tmp, total;
total = 0;
for( m = 0; m < f; m++)
{
for( m = 0; m < f; m++)
{
read(fds[f][0], &tmp, sizeof(int));
sleep(5);
total += tmp;
}
printf("DOne calc \n");
printf("Total: %i \n", total);
}
finish = time(NULL);
float runtime = (float)((finish-start)/RUNS);
printf("runtime: %f \n", runtime);
fclose(fp);
return 0;
}
You get random result for the same input because the calculation based on uninitialized int numb[count]; values.
According to the C99 standard, section 6.7.8.10:
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
Because of it int numb[count]; contains some random junk from memory. To get predictive results use explicit initialization:
#include <string.h> // memset
int numb[count];
memset (numb, 0, sizeof(numb)); // Zero-fills
Use the code bellow to put numbers from filename file into numb:
int i = 0;
char line[1024];
fseek(fp, 0, SEEK_SET);
while(fgets(line, sizeof(line), fp) )
{
if( sscanf(line, "%d", &numb[i]) == 1 ) // One number per line
{
++i;
}
}
Here's my code. Every time I run it, it gives me "Thread 1: breakpoint 1.1" when I assign INT_MAX to min.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main() {
int i, min, max;
min = INT_MAX;
max = INT_MIN;
FILE* fp;
fp = fopen("in.txt", "r");
while (fscanf(fp, "%d", &i) != EOF) {
if (i < min)
min = i;
if (i > max)
max = i;
}
fprintf(fp, "%d %d", min, max);
fclose(fp);
return 0;
}
Try changing:
fprintf(fp, "%d %d", min, max);
With:
printf("%d %d", min, max);
And look what prints in the terminal, are there the right numbers? (I think the answer will be yes).
If what you want is to print the numbers at the end of the file, use this code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main() {
int i, min, max;
min = INT_MAX;
max = INT_MIN;
FILE* fp;
fp = fopen("in.txt", "r");
while (fscanf(fp, "%d", &i) != EOF) {
if (i < min)
min = i;
if (i > max)
max = i;
}
fclose(fp);
fp = fopen("in.txt", "a");
fprintf(fp, "%d %d", min, max);
fclose(fp);
return 0;
}
The breakpoint does not seem related anything in the source at the line specified, probably a breakpoint set and remembered by your debugger.
Your program does not produce the expected output because you attempt to output to the file instead of stdout:
fprintf(fp, "%d %d", min, max);
Just change this line to:
printf("%d %d\n", min, max);
Note that there is another problem: if the file contains any character that is neither a digit nor a whitespace character, fscanf(fp, "%d", &i) will keep returning 0 without consuming this character from the input stream. Even worse, i is not modified if fscanf() returns 0.
You should change the main loop this way:
int n;
while ((n = fscanf(fp, "%d", &i)) != EOF) {
if (n == 1) {
if (i < min)
min = i;
if (i > max)
max = i;
}
}
getc(fp);
}
I'm trying to write a program which will read from text files and then output the minimum, maximum and average values. The trouble I am having is ignoring comments in the text files that begin with a hashtag. Here is my working code so far. Can anyone help?
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
char ch, filename[20];
FILE *lun;
int num, min, max, sum, count, first;
printf("Please enter the name of file to load:");
scanf ("%s", filename);
lun=fopen(filename, "r");
if ( lun != NULL)
{
for ( sum= count= first= 0; fscanf( lun, "%d", &num ) == 1; sum += num, ++count )
if ( !first ) { min= max= num; first= 1; }
else if ( num > max ) max= num;
else if ( num < min ) min= num;
fclose( lun );
printf( " Minimum value: %d\n Maximum value: %d\n Average value: %lf\n",
min, max, sum / (double) count );
}
else
printf( "Unable to read file.\n" );
return 0;
}
Read the data in lines (use fgets()).
If the line contains a #, terminate the string there by replacing the '#' with '\0'. Then scan the line for numbers.
See also How to use sscanf() in loops?
And don't forget to check that the file was opened.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char filename[20];
printf("Please enter the name of file to load: ");
if (scanf("%19s", filename) != 1)
{
fprintf(stderr, "Failed to read file name\n");
return 1;
}
FILE *lun = fopen(filename, "r");
if (lun == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
return 1;
}
char line[4096];
int min = 0; // Avoid compilation warnings (may be used uninitialized)
int max = 0; // Ditto
int sum = 0;
int count = 0;
while (fgets(line, sizeof(line), lun) != NULL)
{
char *hash = strchr(line, '#');
if (hash != NULL)
*hash = '\0';
int pos;
int num;
int off = 0;
while (sscanf(line + off, "%d%n", &num, &pos) == 1)
{
if (count == 0)
min = max = num;
if (num > max)
max = num;
if (num < min)
min = num;
sum += num;
count++;
off += pos; // Skip through line
}
}
fclose(lun);
printf("Minimum value: %d\nMaximum value: %d\nAverage value: %lf\n",
min, max, sum / (double)count);
return 0;
}
If your compiler doesn't support C99 or later, you will have to move variable declarations to the start of a block (immediately after a {).
Handling doubles isn't really any harder:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char filename[20];
printf("Please enter the name of file to load: ");
if (scanf("%19s", filename) != 1)
{
fprintf(stderr, "Failed to read file name\n");
return 1;
}
FILE *lun = fopen(filename, "r");
if (lun == NULL)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
return 1;
}
char line[4096];
double min = 0.0; // Avoids 'used when uninitialized' warnings
double max = 0.0; // Avoids 'used when uninitialized' warnings
double sum = 0;
int count = 0;
while (fgets(line, sizeof(line), lun) != NULL)
{
char *hash = strchr(line, '#');
if (hash != NULL)
*hash = '\0';
int pos;
double num;
int off = 0;
while (sscanf(line + off, "%lf%n", &num, &pos) == 1)
{
if (count == 0)
min = max = num;
if (num > max)
max = num;
if (num < min)
min = num;
sum += num;
count++;
off += pos; // Skip through line
}
}
fclose(lun);
printf("Minimum value: %f\nMaximum value: %f\nAverage value: %f\n",
min, max, sum / count);
return 0;
}