Incomplete image is written using fwrite() - c++

I was writing a code to read and write an image file, but my code works fine except for only one fourth of the image is written when using fwrite()...Please help me find out where i've mistaken.Thanks in advance.
PS I'm a newbie in this field.
This is my code for the read and write functions.
Please ignore any silly things I might have coded to get the work done.
#include<iostream>
#include <cstdlib>
#include <cstdio>
#define FALSE 0
#define TRUE 1
int c,numberOfCols,numberOfRows,HighVal,totalPx,header;
int** a;
int doneReading = FALSE;
char * string;
unsigned char * image;
//Read Image
int readImage(char **argv){
FILE * pFile;
pFile = fopen (argv[1],"rt");
if (pFile==NULL) perror ("Error opening file");
else {
string = (char *)calloc(256,1);
while (!(doneReading) && !feof (pFile)) {
c=(char)getc (pFile);
switch(c){
case 'P':
c=(char)getc (pFile);
switch(c){
case '1':
header=1;
std::cout<<".pbm white n black";
break;
case '2':
header=2;
std::cout<<".pgm greyscale";
break;
case '3':
header=3;
std::cout<<".ppm rgb";
break;
}
c=(char)getc (pFile);
if(c==0x0A) ungetc(c,pFile) ;
break;
case '#':
fgets(string,256,pFile);
std::cout<<"File you entered is "<<string<<"\n";
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
ungetc(c,pFile);
fscanf(pFile,"%d %d %d",&(numberOfCols),&(numberOfRows),&(HighVal));
doneReading=TRUE;
std::cout<<"Done";
std::cout<<"\nNo. of columns: "<<numberOfCols<<"\nNo. of Columns: "<<numberOfRows<<"\nMaximum Intensity: "<<HighVal<<"\n";
break;
}
totalPx=numberOfCols*numberOfRows*1;
image=(unsigned char *)malloc(totalPx);
fread(image,1,totalPx,pFile);
}
std::cout<<"Image read from "<<argv[1]<<"...\n";
}
return totalPx;
}
//Write Image
void writeImage(char **argv,int pixels){
FILE *fOut;
fOut=fopen(argv[2],"wt");
if (fOut==NULL) perror ("Error opening file");
else {
fprintf(fOut,"P%d \n%d %d \n%d",header,numberOfCols,numberOfRows,HighVal);
fwrite(image,1,pixels,fOut);
std::cout<<"Image Written on "<<argv[2]<<"...";
}
}
int main (int argc,char **argv)
{
int pixels;
pixels = readImage(argv);
writeImage(argv,pixels);
return 0;
}

Your problem appears to be with the value returned from readImage(). It's returning the number of pixels without taking into account the size of a pixel. This line:
totalPx=numberOfCols*numberOfRows*1;
returns the number of pixels, but a pixel can be 1, 2, 4 or more bytes. Assuming your image data is RGBA, then you need to multiply that by 4 in the call to either writeImage() or fwrite().

Related

fprintf wont work with switch/case statement in C++

I have a simple C++ program to store pressed keys in file.
What works is prinf to show it in console but fprintf to save it in file won't work.
Even fprintf(logx, "TEST"); works only when i delete while cycle.
My code:
int main(){
char c;
FILE *logx;
logx = fopen("mylog2.txt", "w");
fprintf(logx, "TEST");
while (true)
{
Sleep(10);
for (int i = 8; i <= 255; i++)
{
if (GetAsyncKeyState(i) == -32767)
{
switch(i) {
case 96:
fprintf(logx, "%d", 0);
break;
case 97:
fprintf(logx, "%d", 1);
break;
case 98:
fprintf(logx, "%d", 2);
break;
case 99:
fprintf(logx, "%d", 3);
break;
case 100:
fprintf(logx, "%d", 4);
break;
case 101:
printf("%d", 5);
break;
case 102:
printf("%d", 6);
break;
case 103:
printf("%d", 7);
break;
case 104:
printf("%d", 8);
break;
case 105:
printf("%d", 9);
break;
default:
c = char(i);
printf("%c", c);
break;
}
}
}
}
return 0;
}
File is empty after pressing all possible numbers. Not even TEST is written in file (when while cycle is deleted "TEST" is printed).
Thanks for any help or hint.
You must terminate the loop somehow. If you terminate your program with Ctrl-C the FILE I/O buffers will not be flushed and your file will be empty.
Alternatively you can put an fflush(logx); behind every individual fprintf() statement to force the data out to the file. But this is only a last resort as it makes file I/O very slow.
You should also close the file after the loop:
fclose(logx);

hold screen for accepting arrow keys

for using arrow keys, first it has to be stored for analyzing it. That's why I am using scanf to store it.
But when I try to run this code, and when I press up key, then it is showing ^[[A and when I press enter then this ^[[A removes and program exit without printing printf statement of printf("%s",c). and printf("UP\n").
#include <stdio.h>
int main()
{
char c[50];
scanf("%s",&c);
printf("%s",c);
if (getch() == '\033'){ // if the first value is esc
getch();// skip the [
getch();// skip the [
switch(getch()) { // the real value
case 'A':
printf("UP\n");
break;
case 'B':
printf("DOWN\n");
break;
}
}
return 0;
}
You will find it easy if you use the ncurses library. Just go through the documentation to see how to install it.
After installing read the part on Interfacing with the key board
Here is a sample code
#include <ncurses.h>
int main()
{
int ch;
initscr();
raw();
keypad(stdscr, TRUE);
noecho();
while(1)
{
ch = getch();
switch(ch)
{
case KEY_UP:
printw("\nUp Arrow");
break;
case KEY_DOWN:
printw("\nDown Arrow");
break;
case KEY_LEFT:
printw("\nLeft Arrow");
break;
case KEY_RIGHT:
printw("\nRight Arrow");
break;
}
if(ch == KEY_UP)
break;
}
endwin();
}

move cursor in c++ using gotoXY and kbhit

I want to move the position of symbol "A" in the terminal via the following code in c++, but the terminal closes and seems it does not enter the for loop. I don't know where I am wrong. I will be grateful if you help me:
'w' should move it up
's' should move it down
'a' and 'd' to right and left
#include <iostream>
#include <conio.h>
#include <string>
#include <Windows.h>
using namespace std;
void goToXY(int x=0,int y=0)
{
HANDLE h=GetStdHandle(STD_OUTPUT_HANDLE);
COORD c;
c.X=x;
c.Y=y;
SetConsoleCursorPosition(h,c);
}
int main()
{
char symbol='A';
int X=0, Y=0;
goToXY(X,Y);
cout<<symbol;
for(;;)
{
if(kbhit())
{
char ch = getch();
switch(ch)
{
case 'w':
goToXY(X,Y-1);
cout<<symbol;
case 's':
goToXY(X,Y+1);
cout<<symbol;
case 'a':
goToXY(X-1,Y);
cout<<symbol;
case 'd':
goToXY(X+1,Y);
cout<<symbol;
}
}
getch();
return 0;
}
}
1) You forgot to add break; after each case-body.
2) And you've put return 0; in the body of for-loop, so your program stops after first iteration.
Try this:
for(;;)
{
if(kbhit())
{
char ch = getch();
switch(ch)
{
case 'w':
goToXY(X,Y-1);
cout<<symbol;
break;
case 's':
goToXY(X,Y+1);
cout<<symbol;
break;
case 'a':
goToXY(X-1,Y);
cout<<symbol;
break;
case 'd':
goToXY(X+1,Y);
cout<<symbol;
break;
}
}
}
getch();
return 0;
You have not used the break; statement after each case in your switch statement. Hope this helps.
switch(ch)
{
case 'w':
goToXY(X,Y-1);
cout<<symbol;
break;
case 's':
goToXY(X,Y+1);
cout<<symbol;
break;
case 'a':
goToXY(X-1,Y);
cout<<symbol;
break;
case 'd':
goToXY(X+1,Y);
cout<<symbol;
break;
}

why isnt initgraph getting recognized in my program?

I have programmed a code for displaying a GUI menu in Turbo C++ but I don't know why it wont recognize initgraph
This is the output message
BGI Error:Graphics not initialized
when i tried a simpler program on graphics in Turbo C++ it said egavga.bgi not found but it was there in the bgi file in my turbo c++ folder
Also when i tried to put the location of the bgi in initgraph it doesnt do anything
this is the program code
#include<iostream.h>
#include<conio.h>
#include <dos.h>
#include<graphics.h>
//Menu Global Item
#define pixTOrc(x) (8*(x-1)) //convert pixel into row and col format
#define INC 5 //Increment Distance Between Menu Items
#define ROW 15 //Row Value for Menu Item
#define COL 8 //Column Value for Menu Item
#define MAXMENU 5 //Total menu items
// To display the Inventory Main menu options
typedef char option[20];
option MMenu[]= {
"View Account",
"Transactions",
"New Accont",
"Edit Account",
"Quit"
};
// Function to displays all the menu prompt messages from the pointer array of option a[]
void normalvideo(int x,int y,char *str)
{
x=pixTOrc(x);
y=pixTOrc(y);
outtextxy(x,y,str);
}
// Function to move the cursor on the menu prompt with a reverse video color
void selectedMenu(int x,int y,char *str)
{
x=pixTOrc(x);
y=pixTOrc(y);
setcolor(5); //Selected Item Color
sound(400);
delay(100);
nosound();
outtextxy(x,y,str);
setcolor(WHITE); //Unselected Item Color
sound(500);
delay(100);
nosound();
}
//Keep Track of which arrow key is pressed
char menu()
{
settextstyle(TRIPLEX_FONT,HORIZ_DIR,2);
setcolor(WHITE); //Initial Menu Item Color
int i,done;
for(i = 1; i < MAXMENU; i++)
normalvideo(COL, (i*INC)+ROW, MMenu[i]);
selectedMenu(COL,ROW, MMenu[0]);
i = done = 0;
do
{
/**Status Bar Code**/
setfillstyle(SOLID_FILL,BLUE);
settextstyle(SMALL_FONT,HORIZ_DIR,5);
bar(pixTOrc(2),pixTOrc(52.5),pixTOrc(75),pixTOrc(55));
setcolor(LIGHTCYAN);
switch(i)
{
case 0 : outtextxy(pixTOrc(5),pixTOrc(52.75),"View Account --> View Detail of an account");
break;
case 1 : outtextxy(pixTOrc(5),pixTOrc(52.75),"Transactions --> Do transaction Debit/Credit");
break;
case 2 : outtextxy(pixTOrc(5),pixTOrc(52.75),"New Accont --> Create a new account for customer");
break;
case 3 : outtextxy(pixTOrc(5),pixTOrc(52.75),"Edit Account --> Edit an existing account");
break;
case 4 : outtextxy(pixTOrc(5),pixTOrc(52.75),"Close the Program");
break;
}
/**status Bar ends**/
setcolor(WHITE);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,2);
int key = getch();
switch (key)
{
case 00: key = getch();
switch (key)
{
case 72: normalvideo(COL, (i*INC)+ROW, MMenu[i]);
i--;
if (i == -1)
i = MAXMENU-1;
selectedMenu(COL,(i*INC)+ROW,MMenu[i]);
break;
case 80: normalvideo(COL, (i*INC)+ROW, MMenu[i]);
i++;
if (i == MAXMENU)
i = 0;
selectedMenu(COL, (i*INC)+ROW, MMenu[i]);
break;
}
break;
case 13: done = 1;
}
}
while (!done);
return(i+49);
}
//This part you can use for main functionality of the menu
void mainArea()
{
setcolor(BLUE);
outtextxy(pixTOrc(30),pixTOrc(20),"http://cbsecsnip.in/");
setcolor(YELLOW);
}
/* Code for displaying the main menu*/
void call_menu()
{
char choice;
do
{
choice = menu();
switch (choice)
{
case '1': setcolor(BLUE);
outtextxy(pixTOrc(40),pixTOrc(15),"View Account");
mainArea();
getch();
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar(pixTOrc(28),pixTOrc(14),pixTOrc(75),pixTOrc(50));
mainArea();
break;
case '2':
setcolor(BLUE);
outtextxy(pixTOrc(40),pixTOrc(15),"Transactions");
mainArea();
getch();
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar(pixTOrc(28),pixTOrc(14),pixTOrc(75),pixTOrc(50));
mainArea();
break;
case '3':
setcolor(BLUE);
outtextxy(pixTOrc(40),pixTOrc(15),"New Accont");
mainArea();
getch();
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar(pixTOrc(28),pixTOrc(14),pixTOrc(75),pixTOrc(50));
mainArea();
break;
case '4':
setcolor(BLUE);
outtextxy(pixTOrc(40),pixTOrc(15),"Edit Account");
mainArea();
getch();
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar(pixTOrc(28),pixTOrc(14),pixTOrc(75),pixTOrc(50));
mainArea();
break;
case '5': //Close the project
setcolor(BLUE);
outtextxy(pixTOrc(40),pixTOrc(15),"Quit");
mainArea();
delay(1000);
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar(pixTOrc(28),pixTOrc(14),pixTOrc(75),pixTOrc(50));
mainArea();
goto exit;
}
} while (choice != MAXMENU);
exit:
}
void main()
{
int i,j;
int gd=DETECT,gm;
initgraph(&gd,&gm,"");
setcolor(BLACK);
rectangle(0,0,640,480);
setfillstyle(SOLID_FILL,LIGHTGRAY);
bar(2,1,637,478);
setfillstyle(SOLID_FILL,BLACK);
bar(1,3,637,50);
settextstyle(BOLD_FONT,HORIZ_DIR,2);
setcolor(YELLOW);
outtextxy(pixTOrc(12),pixTOrc(1)," BANKING SYSTEM PROJECT ");
setfillstyle(CLOSE_DOT_FILL,DARKGRAY);
bar(pixTOrc(7),pixTOrc(14),pixTOrc(25),pixTOrc(50));
call_menu();
closegraph();
getch();
}
Possible Solutions:
Copy all Files from BGI folder to BIN.
Check if it works.

Segmentation fault - Core Dumped error while using getopt

I know this queston has been asked multiple times, but still I am unable to figure this out
#include<stdio.h>
#include<getopt.h>
int ch;
int queue_time=60;
int thread_num=4;
char *scheduling_algo="FCFS";
extern char *optarg;
int port=8080;
int debug_flag,h_flag,l_flag;
int main(int argc,char *argv[])
{
while ((ch = getopt(argc, argv, "dhlprtns")) != -1)
switch(ch)
{
case 'd':
debug_flag=atoi(optarg); /* print address in output */
break;
case 'h':
h_flag=atoi(optarg);
break;
case 'l':
l_flag=atoi(optarg);;
break;
case 'p':
port = atoi(optarg);
break;
case 'r':
printf("%s",optarg);
break;
case 't':
queue_time = atoi(optarg);
break;
case 'n':
thread_num = atoi(optarg);
break;
case 's':
scheduling_algo = optarg;
break;
default:
printf("nothing was passed");
}
printf("%d",queue_time);
printf("%d",debug_flag);
printf("%d",h_flag);
printf("%d",l_flag);
}
I am executing my program using the following command
./a.out -d -h -l -t 55
I am getting the core dumped error . I read a few examples on google, but still I am facing this problem. Can anyone please help?
You need to read the man page for getopt()
while ((ch = getopt(argc, argv, "dhlprtns")) != -1)
^^^^^^^^
This does not correspond to the way you are using the arguments. You
want colons ":" after the flags which expect arguments. In your code
"d" is not followed by a colon and yet you seem to want an value for it:
case 'd':
debug_flag=atoi(optarg); /* print address in output */
break;
So what is happening is you are calling atoi(0) and this is seg faulting.
Here's the example from the man page, note how "b" is not followed by a
colon while "f" is.
#include <unistd.h>
int bflag, ch, fd;
bflag = 0;
while ((ch = getopt(argc, argv, "bf:")) != -1) {
switch (ch) {
case 'b':
bflag = 1;
break;
case 'f':
if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
(void)fprintf(stderr,
"myname: %s: %s\n", optarg, strerror(errno));
exit(1);
}
break;
case '?':
default:
usage();
}
}
argc -= optind;
argv += optind;
This may be of use to others: You will also get a segfault if you specify an option letter as both without colon, and with colon eg "dabcd:e" - in this case "d" occurs with and without colon.... and then use that option letter.
It appears getopt and its variants do not check for this conflict and return an error!