Can't create ppm File from an executable (C) - c

I am trying to create a ppm file from inside a C program, but somehow it doesn't work.
It works fine when I am inside the IDE and run the program there. The program is executed and the file created inside the file's folder.
But once I build it and open the executable with a double click, the program runs in the terminal but does not create the file.
I am working on a mac and this is the relevant code, thanks in advance you all!
// from generalSettings.h
#define WIDTH 1100
#define HEIGHT 966
#define MYFILENAME "testimage.ppm"
int pictureArray[HEIGHT][WIDTH];
//from the main.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "generalSettings.h"
int main()
{
triangle firstParentTriangle;
// these two functions "draw" sierpinsky triangles in the pictureArray
drawFirstParentTriangle(&firstParentTriangle);
drawChildTriangles(firstParentTriangle, numberOfRecursions);
create_ppm();
return 0;
}
void create_ppm()
{
unsigned char color_black[] = "000 000 000\n";
unsigned char color_white[] = "255 255 255\n";
FILE *p_file = fopen(MYFILENAME, "w");
if (NULL != p_file)
{
fprintf(p_file, "P3\n %d %d\n 255\n", WIDTH, HEIGHT);
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++)
if (1 == pictureArray[i][j])
fprintf(p_file, color_black);
else
fprintf(p_file, color_white);
fclose(p_file);
}
}
Here, I have replaced the foreground and background variables with local ones.
Generally, the program inserts 1 to the pictureArray[][] on certain elements and leaves others with a 0.
For my problem, this should be the relevant code for a reproducable example.
EDIT: Problem solver. File was created in the user folder due to missing path.

Related

How can I see if I have reached beginning of file?

I have a task to rewrite the Unix system function tail. My algorithm works in the following way:
I lseek to the end of the file, enter a loop, move the file descriptor a bit back, read a couple of bytes, and if I find any new lines, I increase the counter. Once, I get 10 new lines ( I think it should be 11, but the thing is not finished yet and this works for me for now ), I leave the loop.
If the file has less than 10 new lines, I get into an infinite loop, because of the way I wrote it.
Is there a way to see if I have reached the beginning of the file, so I can leave the loop then?
Code :
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main (int argc, char *argv[])
{
int fd;
off_t offset = 10;
size_t size = 10;
unsigned char buff[10];
int new_line_counter = 0;
off_t total_offset = 0;//dont mind this
fd = open("a.txt", O_RDONLY);
if (fd == -1)
{
perror("open");
return 1;
}
lseek(fd,0,SEEK_END);
while (new_line_counter < 10)
{
lseek(fd,-offset,SEEK_CUR);
total_offset+=10;//dont mind this
for(int i = 0; i<10;i++)
{
if(buff[i]=='\n')
{
if(new_line_counter==10)break;
new_line_counter++;
//printf("%d",new_line_counter);
}
}
read(fd,buff,size);
lseek(fd,-offset,SEEK_CUR);
}
}
Use the return value of lseek. It will return the current file position, or, -1 on error.
You first lseek(fd,0,SEEK_END) will give you the file size.
Use that to keep track the current file position (and make sure that to adjust 'offset' so that lseek(fd,-offset,SEEK_CUR); will never seek before file begin.
This is necessary, otherwise you might miss the first line.
lseek() returns a value, it's either the new offset or -1. Check for that value like this:
while (new_line_counter < 10)
{
if (-1==lseek(fd,-offset,SEEK_CUR)) break;

How to write numbers in text files in embedded C

I'm working with an EFM32wg280f256 and I would like to debug the code that I'm writing in the following manner: opening a file in SD memory and write the content of the buffers I'm using.
This is a minimal example of my attempt:
#include <stdbool.h>
#include "ff.h"
#include <stdio.h>
#include <complex.h>
#include "arm_math.h"
#include "audioMoth.h"
#define NUMBER_OF_SAMPLES_IN_BUFFERS_DATA 4
static float32_t* buffersDATA[12];
int main(void) {
//Create buffers
buffersDATA[0] = (float32_t*)AM_EXTERNAL_SRAM_START_ADDRESS;
for (int i = 1; i < 12; i += 1) {
buffersDATA[i] = buffersDATA[i - 1] + NUMBER_OF_SAMPLES_IN_BUFFERS_DATA;
}
//Example of collected data
float32_t var0[] = {-29.499557,-67.498978,-54.499176,-53.499191};
//Pass collected data to one of created buffers
for (int j = 0; j <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; j+= 1){
*(buffersDATA[0]+j) = var0[j];
}
//Initialize file system
AudioMoth_enableFileSystem();
// Write text file
FIL fpt;
f_open(&fpt,"dataVAR.txt", FA_CREATE_ALWAYS | FA_WRITE);
for (int i = 0; i <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; i+= 1){
char str[8];
sprintf(str, "%d, ", (int)var0[i]);
f_puts(str,&fpt);
}
f_close(&fpt);
// Write another text file
FIL fptr;
f_open(&fptr,"data.txt", FA_CREATE_ALWAYS | FA_WRITE);
for (int i = 0; i <NUMBER_OF_SAMPLES_IN_BUFFERS_DATA; i+= 1){
char str[8];
sprintf(str, "%d, ", (int)*(buffersDATA[0]+i));
f_puts(str,&fptr);
}
f_close(&fptr);
}
Typecasting is because sprintf does not support float values, but integer is enough for me to know if I am doing OK or not.
When I open dataVAR.txt:
-29, -67, -54, -53,
But data.txt:
0, 0, 0, 0,
when they should be the same.
I've tried the same in a executable (adapting it) to verify that I am correctly passing the values (it seems so).
Where is the problem?
Thanks in advance.
Ok, the problem was that I didn't initialize communication between the microcontroller and the external chip of SRAM.
I did and all worked as expected.

Visual Studio Code: Error include external header in C

New to programming, actually following an open classroom tutorial on C and I'm finding myself stuck on that including external header part. I use an IDE, I'm on Visual Studio Code, I could switch to an IDE but it should be possible and not to difficult to do it in a simple text editor so I want to understand how.
The error code when running the program:
main.c:6:10: fatal error: 'level.h' file not found
#include "level.h"
^~~~~~~~~
1 error generated.
Here's my main.c code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <string.h>
#include "level.h"
#include "menu.h"
int level();
int menu();
int main()
{
int nombreMystere, guess, round = 10;
char answer;
bool exit = true;
while (exit)
{
menu();
{
while(guess != nombreMystere)
{
printf("%d" , nombreMystere);
printf("\nIl vous restes %d round.\n", round );
printf("Trouver le nombre magique: " );
scanf ("%d" , &guess );
if(guess < nombreMystere) printf("Trop bas\n");
else if(guess > nombreMystere) printf("Trop Haut\n");
round --;
if (round == 0)
{
printf("You Lose.. Dumbass");
break;
}
if (guess == nombreMystere) printf("\nGood job !\n");
}
printf("Play again?\n (yes/no): ");
scanf("%s", &answer);
if (answer == 110 || answer == 78) {exit=0;}
}
}
return 0;
}
Here's level.c:
static int selec;
int level(int x)
{
int max, difficulty = selec;
if (difficulty==1){max = 100 ;}
else if (difficulty==2){max = 1000 ;}
else if (difficulty==3){max = 10000 ;}
return max;
}
level.h:
int level(int x);
menu.c:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "menu.h"
int level();
int menu()
{
srand(time(NULL));
int max, nombreMystere, selec;
const int MIN = 1;
while (selec < 1 || selec > 3)
{
printf("\n\nSelect Difficulty level:\n");
printf("1: Level 1\n");
printf("2: Level 2\n");
printf("3: Level 3\n");
scanf("%d", &selec);
level(selec);
printf("\n\n%d\n\n", max);
//if (difficulty==1){max = 100 ;}
//else if (difficulty==2){max = 1000 ;}
//else if (difficulty==3){max = 10000 ;}
//else {printf("Wrong selection, please try again.");}
nombreMystere = (rand() % (max - MIN + 1)) + MIN;
}
return nombreMystere;
}
menu.h:
int menu();
I've been searching the whole day on the internet a way to fix this issue but I don't understand half of what I'm seeing and every topic was talking only about C++. I've seen somewhere that it could come from the tasks.json file in VSCode but it was on a C++ topic.
I'm using macOS.
Thanks for your time.
EDIT: Both .h and .c files are in separate folders and both folders are in the same directory.
The level.h file needs to be in the SAME folder as main.c.
Also the menu.h file should be in the same folder. So make sure you have all the files in the same folder.
Additionally these two lines shouldn't be in your main.c:
int level();
int menu();
Since this is essentially what including the headers does for you. On that note I also can't see you calling the function level() in your main.c file, thus you do not even need to include the level.h file at all. However you do call the function menu() so you do need to #include "menu.h" like you are doing.
Also in the menu.c file you don't need this line #include "menu.h", you should change it to #include "level.h" since you are calling the level() function in your code and then also remove the line after it, that is; the line int level();, since that's essentially what including the level header will do for you.
The level.c file looks fine to me.
If you're still getting an error with all the files in the same folder, make sure you are compiling it correctly.
In include "x" the value of x represents the path to your header file (relative using the directories . and .. in your current directory or absolute paths, the latter is a BAD PRACTICE don't do it, but you can, side note: the ~ is not supported) if all your files are in the same directory you shouldn't have such an error, you don't have to use the relative path it assumes the current directory by default, but if they aren't consider including them the right way. see sveinnth's answer for more notes about your coding style.
one more thing, you should include your compilation options in your question.

Ncurses - multiple windows and refreshing

I'm writing a small school project. It's a game of falling words - the word is moving from the top to the bottom. I had an idea to make two windows (one with interface and second with moving object). Words are randomized as you can see in the code. The problem is the input. I'm using mvwsacanw to write the word. Is there any way to write anything in second window while the word is moving in different window? For now the word is falling and when it reaches the bottom, the second window opens and I can type the word.
Hope somebody will help me.
#include <stdio.h>
#include <ncurses.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
void moving(WINDOW *move)
{
int j,random;
char *cmp=(char*)malloc(10*sizeof(char));
char word[6];
wclear(move);
box(move, 0, 0);
mvwprintw(move, 1, 1, "PIS");
wrefresh(move);
srand (time (NULL));
random=2+rand()%7;
for(j=0; j< random ; j++) //random word
{
word[j]= rand()%26+'a';
}
int poz = 2+rand()%24; //random position of moving word
for(int i=1; i<18; i++)
{
wclear(move);
box(move,0,0);
mvwprintw(move,i, poz, word);
wrefresh(move);
usleep(300000);
}
}
void interface(WINDOW *ui)
{
wclear(ui);
char *cmp=(char*)malloc(10*sizeof(char));
box(ui, 0, 0);
mvwprintw(ui,1,1,"wpisz wyraz: ");
mvwscanw(ui,2,1, "%s",cmp);
mvwprintw(ui, 3, 1, "->%s",cmp);
wrefresh(ui);
}
int main(int argc, char *argv[])//int argc, const char * argv[])
{
int x,y;
int sc = 3;
initscr();
noecho();
curs_set(FALSE);
getmaxyx(stdscr, y,x);
WINDOW *move = newwin(y-5, x-1, 0, 0);
WINDOW *ui = newwin(sc+2, x, y-5, 0);
while(1)
{
moving(move);
interface(ui);
wclear(move);
wclear(ui);
}
delwin(move);
delwin(ui);
endwin();
return 0;
}
You can't do that with your current code structure. You are keeping the word fall phase and the input phase in separate functions, so the only way to make them work at the same time is some kind of multithreading.
Assuming this is not what you want to do, you could try to merge the two features in a single function. In pseudocode:
pick random word
pick random position
set i = 0
set input = {} //empty array
do
> print word at (i, pos)
> set stoptime = time() + DELAY
> do
>> set c = getch()
>> append c to input
>> print interface
> while (time() < stoptime)
> i++
while (i < 18)
This, with timeout() set to an opportune delay, will give the impression that everything is happening simultaneously.
This is absolutely not the most efficient solution, but is simple and straightforward, and considering you are working on a school project, it should be just fine
Try to use the following code :
nodelay(your_window, TRUE);
which will make your input nonblocking for the given window !

Values of an array changing randomly during execution

I'm trying to make a little programme in C using SDL, displaying a robot moving on a grid. This grid is represented by a txt file of 0s and 1s.
Here is the fonction creating an array from the txt file, which works.
// create a map(array) from a text file
int (*newMap())[SIZE_HEIGHT][SIZE_WIDTH]
{
static const char filename[] = "input.txt"; /* the name of a file to open */
FILE *file = fopen(filename, "r"); /* try to open the file */
int map[SIZE_HEIGHT][SIZE_WIDTH];
char line[BUFSIZ]; /* space to read a line into */
int k = 0;
while ( fgets(line, sizeof line, file)!=NULL && k<SIZE_HEIGHT) /* read each line */
{
int i;
char *token = line; /* point to the beginning of the line */
for ( i = 0; i<SIZE_WIDTH; i++ )
{
map[k][i]=((int)*token)-48;
token+=sizeof(char);
printf("map[%d][%d]=%d\n", (int)k,(int)i,map[k][i]);
}
puts("----\n");
k++;
}
fclose(file);
int (*p)[SIZE_HEIGHT][SIZE_WIDTH];
p=&map;
return p;
}
Then I try to put the grid on the sreen (not the whole fonction):
#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <time.h>
#include <string.h>
#include "Parameters.h"
#include "simulation.h"
#include "editor.h"
void simulate(SDL_Surface *ecran)
{
SDL_Surface *carreVert = SDL_LoadBMP("carreVert.bmp");
SDL_Surface *carreRouge = SDL_LoadBMP("carreRouge.bmp");
SDL_Surface *robot = SDL_LoadBMP("robotRouge.bmp");
SDL_SetColorKey(robot, SDL_SRCCOLORKEY, SDL_MapRGB(robot->format, 255, 255, 255));
int (*map)[SIZE_HEIGHT][SIZE_WIDTH];
map=newMap();
SDL_Rect positionFond;
int i;
int j;
for(j=0; j<SIZE_HEIGHT; j++)
{
for(i=0; i<SIZE_WIDTH; i++)
{
positionFond.x = 100*i;
positionFond.y = 100*j;
if((*map)[j][i]+1)
{
SDL_BlitSurface(carreVert, NULL, ecran, &positionFond);
}else
{
SDL_BlitSurface(carreRouge, NULL, ecran, &positionFond);
}
}
}
And then something strange happens: when I observe the array *map with the debugger, I see that the values are changing when I go through the test. So the grid does appear, but not with the right pattern. Why does that happen?
Edit:no error an compiler.
Edit: Any guess of what might do that would be gladly accepted.
The array map is local to the function. It ceases to exist when the function finishes. You pass its address to the caller, but when the caller tries to use it ... BANG!
Fast solution: make the array map a static one: make sure you never call newMap more than once per run.
Other solutions:
move the creation of the array outwards and pass the address around
use malloc and friends to manage the array
You are returning a pointer to an object with automatic storage duration (an array that gets "deallocated" on return from the function where it is declared), so you end up seeing random garbage.

Resources