C does not go to the next line while reading .ppm - c

So I have a .ppm file and the goal is to read each pixel to corresponding r[] g[] and b[] elements. The code reads the first line (idk correct or not), but it does not go any further. I'm unsure if I need these getc(fp); in order to skip spaces. Reading each line and parsing it to int is not an option. Thanks for any help.
int main(int argc, char** argv)
{
int height;
int width;
int max;
FILE *fp;
fp = fopen("vit_small.ppm", "r");
fscanf(fp, "%*[^\n]\n", NULL);
fscanf(fp, "%d %d", &width, &height);
printf("Width is %d height is %d \n", width, height);
fscanf(fp, "%d", &max);
printf("Maximum value %d \n", max);
int r [height][width];
int g [height][width];
int b [height][width];
int hist [5];
int w = 0;
int h = 0;
char buffer [1000];
for (;w<height;w++)
{
printf("Row number %d \n", w);
for (;h<width;h++)
{
fread(&r[w][h], 1, 1, fp);
printf("%d ", r[w][h]);
getc(fp);
fread(&g[w][h], 1, 1, fp);
printf("%d ", g[w][h]);
getc(fp);
fread(&b[w][h], 1, 1, fp);
printf("%d ", b[w][h]);
getc(fp);
}
getc(fp);
printf("\n");
}
int i = 0;
int j = 0;
for (;i<height; i++)
{
for (;j<width; j++)
{
printf("%d %d %d ", r[i][j], g[i][j], b[i][j]);
}
printf("\n");
}
fclose(fp);
FILE * res;
res = fopen ("Image_output.ppm", "w");
fprintf (res, "P6\n");
fprintf(res, "%d\n", width);
fprintf(res, "%d\n", height);
fprintf(res, "%d\n", max);
i = 0;
j = 0;
for(; i < height; i++)
{
for(; j < width; j++)
{
fprintf(res, "%d %d %d", r[i][j], g[i][j], b[i][j]);
}
fprintf(res,"\n");
}
return (EXIT_SUCCESS);
}

The P6 format of PPM stores each primary as a byte and there are no rows and no spaces. So if an image is 10 by 6, it will have 180 bytes (10x6x3) following the 255 and newline character. See
Wikipedia entry on PPM.

Related

Fscanf Doesn't Take Inputs properly

I'm trying to take inputs with fscanf and to give output to another file but fscanf doesn't give the input it should give.
Here is my code:
#include <stdio.h>
int main() {
FILE *a;
FILE *b;
int i;
int played_matches, points, goaldif, ranking;
int wins, draws, losses, goals_scored, goals_against;
char team[18];
a = fopen("source.docx", "r");
b = fopen("aim.doc", "w");
for (i = 0; i < 10; i++) {
fscanf(a, "%d %s %d %d %d %d %d", &ranking, &team, &wins, &draws, &losses, &goals_scored, &goals_against);
played_matches = wins + draws + losses;
points = (3 * wins) + draws;
goaldif = goals_scored - goals_against;
fprintf(b, "%d %s %d %d %d ", ranking, team, played_matches, points, goaldif);
}
fclose(a);
fclose(b);
return 0;
}
#include <stdio.h>
int main() {
FILE *a;
FILE *b;
int i;
int played_matches, points, goaldif, ranking;
int wins, draws, losses, goals_scored, goals_against;
char team[18];
a = fopen("source.txt", "r");
b = fopen("aim.txt", "w");
for (i = 0; i < 10; i++) {
fscanf(a, "%d %s %d %d %d %d %d", &ranking, team, &wins, &draws, &losses, &goals_scored, &goals_against);
played_matches = wins + draws + losses;
points = (3 * wins) + draws;
goaldif = goals_scored - goals_against;
fprintf(b, "%d %s %d %d %d \n", ranking, team, played_matches, points, goaldif);
}
fclose(a);
fclose(b);
return 0;
}
& is for integer values.

Why my code is printing last values retrieved from file instead of new one

I have the following code for reading files in C. It's reading from files but not like its supposed to be. It is showing up like this:
instead of like this:
Although I am calling the same print function. We are taking records for 4 employees. I know it's a logical error but I am unable to solve it.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct employee {
float hoursWorked, hourlyRate, federalTax, stateTax;
char name[20];
};
struct calc
{
float grosspay, fto, sto, np;
};
void print(struct employee s[], struct calc c[], int n)
{
for (int i = 0; i < 4; i++)
{
printf("\n%s's gross pay: $%.02f\n", s[i].name, c[i].grosspay);
printf("Federal tax owed: $%.02f\n", c[i].fto);
printf("State tax owed: $%.02f\n", c[i].sto);
printf("Net pay: $%.02f \n\n", c[i].np);
printf("\n");
}
}
void savetext(struct employee s[], struct calc c[], int n)
{
FILE *f;
f = fopen("employee.txt", "w");
for (int i = 0; i < n; i++)
{
fprintf(f, "%s\n", s[i].name);
fprintf(f, "%f %f %f %f\n", s[i].hoursWorked, s[i].hourlyRate, s[i].federalTax, s[i].stateTax);
fprintf(f, "%.2f %.2f %.2f %.2f\n", c[i].grosspay, c[i].fto, c[i].sto, c[i].np);
}
fclose(f);
}
void retrievetext(struct employee s[], struct calc c[], int n)
{
FILE *f;
int length;
f = fopen("employee.txt", "r");
for (int i = 0; i < n; i++)
{
fgets(s[i].name, sizeof(s[i].name), f);
length = (int)strlen(s[i].name);
s[i].name[length - 1] = '\0';
fscanf(f, "%f %f %f %f\n", &s[i].hoursWorked, &s[i].hourlyRate, &s[i].federalTax, &s[i].stateTax);
fscanf(f, "%.2f %.2f %.2f %.2f\n", &c[i].grosspay, &c[i].fto, &c[i].sto, &c[i].np);
}
fclose(f);
}
void savebin(struct employee s[], int n)
{
FILE *f;
f = fopen("employee.bin", "wb");
for (int i = 0; i < n; i++) {
fwrite(&s, sizeof(s[n]), n, f);
}
fclose(f);
}
void retrievebin(struct employee s[], int n)
{
FILE *f;
f = fopen("employee.bin", "rb");
for (int i = 0; i < n; i++) {
fread(&s, sizeof(s[i]), n, f);
}
fclose(f);
}
int main(){
savetext(st, c, 4);
retrievetext(st, c, 4);
printf("After reading text file");
print(st, c, 4);
savebin(st, 4);
retrievebin(st, 4);
printf("After reading bin file");
print(st, c, 4);
return 0;
}
You didn't get a warning here from this?
fscanf(f, "%.2f %.2f %.2f %.2f\n", &c[i].grosspay, &c[i].fto, &c[i].sto, &c[i].np);
fscanf() will eat any float you throw at it, specifying the %.2f format like this doesn't really work.
https://en.wikipedia.org/wiki/Scanf_format_string
Try using it like this:
fscanf(f, "%f %f %f %f\n", &c[i].grosspay, &c[i].fto, &c[i].sto, &c[i].np);
It was probably reading the file wrong, and then using the wrong line as an employee name.
PS: Your print() might have a small error:
for (int i = 0; i < 4; i++) // It should probably be i < n, instead of i < 4
And try to include an example input file, so people can test the code. At main(), there is no definition of st, so it's hard for people to see what's really happening if they can't test it themselves.

comparing floats in two structs

I have a code that reads two .txt files and puts them into structs. Then, I want to compare the x value from each file and find matches. The type of these values is floats. I keep getting incorrect matches and line numbers and I'm not sure what to do. It works for the first few but then it just says there's a match when it is only a value in one file. Everything else works fine, so if anyone has suggestions on comparing the values that would be much appreciated. Thank you.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define FLT_EPSILON 1.19209290E-07F
typedef struct fcat_s {
float x;
float y;
float a_j2000;
float b_j2000;
float mag;
} fcat_s;
typedef struct cat_s {
float num;
float x;
float y;
float xworld;
float yworld;
float flux_auto;
float mag_auto;
float awin;
float bwin;
} cat_s;
int main(void) {
float exptime = 0;
float F = 0;
float Mi = 0;
float Mcat = 0;
float FLUX_AUTO = 0;
float ZP = 0;
char fcatname[50];
char catname[50];
int fcatcount = 0;
int catcount = 0;
char fcat_c;
char cat_c;
float x;
char str[100];
int i = 0;
int j = 0;
float temp;
int match = 0;
printf("Please input the .fcat file name:\n");
scanf("%str", fcatname);
printf("Please input the .cat file name:\n");
scanf("%str", catname);
printf("Please input the exposure time:\n");
scanf("%f", &exptime);
fcat_s *f = (fcat_s *)malloc(sizeof(fcat_s));
cat_s *c = (cat_s *)malloc(sizeof(cat_s));
// .fcat file
FILE *fcat;
fcat = fopen(fcatname, "r");
if (fcat == NULL) {
printf("The input file does not exist\n");
} else {
for (fcat_c = getc(fcat); fcat_c != EOF; fcat_c = getc(fcat)) {
if (fcat_c == '\n')
fcatcount++;
if (fcatcount > 4) {
fscanf(fcat, "%f", &f[fcatcount-5].x);
fscanf(fcat, "%f", &f[fcatcount-5].y);
fscanf(fcat, "%f", &f[fcatcount-5].a_j2000);
fscanf(fcat, "%f", &f[fcatcount-5].b_j2000);
fscanf(fcat, "%f", &f[fcatcount-5].mag);
}
}
}
printf("\n");
printf("The .fcat file has %d lines. \n", fcatcount);
printf("\n");
printf("\n");
printf("FCAT CONTENTS\n");
for (i = 0; i < (fcatcount-5); i++) {
printf("%lf\t %lf\t %lf\t %lf\t %lf\n",
f[i].x, f[i].y, f[i].a_j2000, f[i].b_j2000, f[i].mag);
}
printf("\n");
printf("\n");
// .cat file
FILE *cat;
cat = fopen(catname, "r");
if (cat == NULL) {
printf("The input file does not exist\n");
} else {
for (cat_c = getc(cat); cat_c != EOF; cat_c = getc(cat)) {
if (cat_c == '\n')
catcount++;
if (catcount > 8) {
fscanf(cat, "%f", &c[catcount-9].num);
fscanf(cat, "%f", &c[catcount-9].x);
fscanf(cat, "%f", &c[catcount-9].y);
fscanf(cat, "%f", &c[catcount-9].xworld);
fscanf(cat, "%f", &c[catcount-9].yworld);
fscanf(cat, "%f", &c[catcount-9].flux_auto);
fscanf(cat, "%f", &c[catcount-9].mag_auto);
fscanf(cat, "%f", &c[catcount-9].awin);
fscanf(cat, "%f", &c[catcount-9].bwin);
}
}
}
printf("\n");
printf("The .cat file has %d lines. \n", catcount);
printf("\n");
printf("\n");
printf("CAT CONTENTS\n");
for (i = 0; (i < catcount-9); i++) {
printf("%lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\t %lf\n",
c[i].num, c[i].x, c[i].y, c[i].xworld, c[i].yworld,
c[i].flux_auto, c[i].mag_auto, c[i].awin, c[i].bwin);
}
printf("\n");
printf("\n");
// searching in the files for a match
for (i = 0; (i <= (fcatcount-5)); i++){
for (j = 0; (j <= (catcount-9)); j++) {
if (fabs(f[i].x - c[j].x) < FLT_EPSILON && fabs(f[i].y - c[j].y) < FLT_EPSILON) {
printf("%f\t .fcat line: %d\t .cat line: %d\n", c[j].x, i, j);
match++;
}
}
}
printf("\n");
printf("\n");
printf("The files have %d matches. \n", match);
fclose(fcat);
fclose(cat);
free(f);
free(c);
return 0;
}
You only allocated space for one fcat_s:
fcat_s *f = (fcat_s*)malloc(sizeof(fcat_s));
But in your first loop, you are already treating f like an array:
...
fscanf(fcat, "%f", &f[fcatcount-5].x);
...
Unless I am missing something, it seems that you are reading and writing to unallocated memory. I am surprised your program doesn't segfault.

Problem with printf or scanf (wont print the number properly)

I am trying to read numbers from file, the function prints only the digits after the decimal point. any idea why this happens?
thanks!
float Read() {
int i, k, w, m, n, j;
float number;
float a[m];
FILE *fil1;
fil1 = fopen("numbers.txt", "r");
w = 0; k = 0;
while (fscanf(fil1, "%d", &n) != EOF) {
fscanf(fil1, "%f", &number);
a[k] = number;
printf("%d => %f \n", i, a[k]);
w++;k++;
}
}
You're scanning the file twice, you're basically skipping every second number. this should fix it.
float Read (){
int i,k,w,m,n,j;
float number;
float a[m];
FILE *fil1;
fil1 = fopen("numbers.txt","r");
w=0; k = 0;
while (fscanf(fil1, "%f", &n) != EOF){
a[k]=n;
printf ("%d => %f \n",i, a[k]);
w++;k++;}
change n to be float
and read it as float:
#include "stdio.h"
#pragma warning(disable : 4996)
float Read()
{
int k, w;
float n;
float a[100];
FILE* fil1;
fil1 = fopen("numbers.txt", "r");
w = 0; k = 0;
while (fscanf(fil1, "%f", &n) != EOF) {
a[k] = n;
printf("%f \n", a[k]);
w++; k++;
}
return 0;
}

Reverse Grayscale Image Pixel by Pixel

I'm trying to write a C program that takes a .raw grayscale image and reverses it, pixel by pixel.
I store each pixel in a 1D char array, and then write each pixel to an output file, just in opposite order.
My program works if I try to reproduce the image, but if I try modifying the indices of my array, I produce an unreadable file.
Reproduce Original
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fin, *fout;
char ipath[64], opath[64], *rev, px;
int i, row, read, width, height;
printf("Name of input file: ");
scanf("%s", ipath);
printf("Name of output file: ");
scanf("%s", opath);
printf("Width of image: ");
scanf("%d", &width);
printf("Height of image: ");
scanf("%d", &height);
fin = fopen(ipath, "rb");
fout = fopen(opath, "wb");
rev = (char *)malloc(width * sizeof(char));
row = 0;
while(row < height)
{
for(i = 0; i < width; i++)
{
read = fread(&px, sizeof(char), 1, fin);
rev[i] = px;
}
for(i = 0; i < width; i++)
if(i < width && row < height)
fwrite(&rev[i], sizeof(char), 1, fout);
row++;
}
fclose(fout);
fclose(fin);
return 0;
}
Reverse Image
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fin, *fout;
char ipath[64], opath[64], *rev, px;
int i, row, read, width, height;
printf("Name of input file: ");
scanf("%s", ipath);
printf("Name of output file: ");
scanf("%s", opath);
printf("Width of image: ");
scanf("%d", &width);
printf("Height of image: ");
scanf("%d", &height);
fin = fopen(ipath, "rb");
fout = fopen(opath, "wb");
rev = (char *)malloc(width * sizeof(char));
row = 0;
while(row < height)
{
for(i = 0; i < width; i++)
{
read = fread(&px, sizeof(char), 1, fin);
rev[width - 1 - i] = px;
}
for(i = 0; i < width; i++)
if(i < width && row < height)
fwrite(&rev[i], sizeof(char), 1, fout);
row++;
}
fclose(fout);
fclose(fin);
return 0;
}
For testing purposes, I've just used scanf() though I'm aware of its issues.

Resources