I have some weird issue with c program. I am learning c programming on-line and I practise some exercise. On of them is about a imagery technic called erosion. Imagine there is an image with two types of pixels symbolized by either '.' or '#'. When a pixel is surrounded by 4 '#' character, it is preserved, and in the other case it is replaced by a '.' character. The input is N the number of times the erosion is applied, H and L the height and width of the image, and a rectangle of characters composed by '.' and '#' character.
For instance input :
1 //N
4 //H
4 //L
....
.###
####
####
and the output is
....
....
.##.
....
The problem is that the on-line compiler (that tests a random serie of inputs) rejects my code telling that the memory is overflowed
Here is the code
#include <stdlib.h>
#include <stdio.h>
//test wether a pixel is surrounded by 4 '#' characters
char test(int i, int j,int H, int L, char c[H][L]){
int k=0;
int l=0;
char result='-';
if((i==0)||(i==H-1)||(j==0)||(j==L-1)){
result='+';
}
else{
for(k=0;k<2;k++){
for(l=0;l<2;l++){
if(c[i+(1-2*k)*l][j+(1-2*k)*(1-l)] =='.'){
result='+';
break;
}
else{
}
}
if(result=='+'){break;}
else{}
}
}
return result;
}
//The erode function that replaces the image by one in which '#' characters are replaced by '.' characters when it is not surrounded by 4 '#' characters
char **erode(int H, int L, char c[H][L]){
int i;
int j;
char ch='-';
char **d = malloc (H * sizeof (int *));
for (i = 0; i < H; i++) {
d[i] = malloc (L * sizeof (int));
}
i=0;
for (i=0;i<H;i++)
{
for (j=0;j<L;j++)
{
ch=test(i,j,H,L,c);
if(ch=='+'){
d[i][j]='.';
}
else{
d[i][j]=c[i][j];
}
ch='-';
}
}
for (i= 0; i < H; i++) {
free(d[i]);
}
free(d);
return d;
}
//here are computed the inputs and outputs
int main()
{
int i=0;
int j=0;
int N;
int H;
int L;
char o;
scanf("%d",&N);
scanf("%d",&H);
scanf("%d",&L);
scanf("%c",&o);
char c[H][L];
char d[H];
char ero[H][L];
while (i<H)
{
while (j<L)
{
scanf("%c",&c[i][j]);
j++;
}
j=0;
scanf("%c",&d[i]);
i++;
}
int l;
int m;
int n;
for(l=0;l<N;l++){
for (i=0;i<H;i++)
{
for (j=0;j<L;j++)
{
ero[i][j]=erode(H,L,c)[i][j];
}
}
for (m=0;m<H;m++)
{
for (n=0;n<L;n++){
c[m][n]=ero[m][n];
}
}
}
for (i=0;i<H;i++)
{
for (j=0;j<L;j++){
printf("%c",c[i][j]);
}
printf("\n");
}
}
(The code is far from being optimal because I tried to debugg it and to make something really decomposed)
Does anyone has an idea why I have this message error?
This is probably because within your erode function you are using malloc a number of times but never calling free. You actually call erode inside a triple loop from main. This suggests it could be getting called many times but as the allocated memory never gets released it is entirely possible that your memory is getting exhausted which explains the error message. Take more care to release the memory using free when you no longer need it.
Related
and thanks for your time. I apologize in advance I am new to C programming and posting on stack overflow. Any information I may have left out and questions you have please ask.
I have this lab I am working on for my class and I'm having trouble understanding how the dreaded pointers operate. First I will explain the lab instructions.
First, I am to create an array of 200 words with a max length of 30+1 for null.
Next, call functions I need to create which include:
A read function which reads words from a file into the array. I must use fopen and fscanf functions.
A function to convert a string to lowercase using the ASCII codes of each character. (Must use pointers)
A function to return the length of a string.(Can't use strlen function and must use pointers)
A function with three parameters(array of words, # of words in array, and an int length). Function returns the number words in the array that match the int length.
A print function to print all the words in the array.
The IDE I am using is Dev C++ its been wonky so I have also been using netbeans.
I have only attempted to create the read, print, and converting to lowercase functions. I first tried to read the file and print the array in main. The file I'm reading is created by me it contains a short sentence which follows exactly:
There ARE so MANY words in HERE
EDIT- Updated main code to current with working lowercase loop inside main.
#define rows 200 //How many words allowed in array.
#define cols 31 //How many characters allowed for each word.
void lowercase(char* words, int count);
int read(char (*words)[cols]);
void print(char (*words)[31], int count);
int main(int argc, char *argv[]){
char words[rows][cols];
int i, j;
int count = read(words);
print(words, count);
/*
//make words lowercase
for(i = 0;i<count;i++){
for(j = 0;j<cols;j++){
if(words[i][j]!=0){
if(words[i][j]<91 && words[i][0]>64)
words[i][j] = words[i][j]+32;
}
}
}*/
for(i = 0;i < count;i++){
lowercase(*words+i, count);
}
print(words, count);
return 0;
}
The code is poorly written and managed properly I'm just trying to get everything to work first then it will be more appropriate. The first printf output comes out how it should:
Array [0]: There
Array [1]: ARE
Array [2]: so
Array [3]: MANY
Array [4]: words
Array [5]: in
Array [6]: HERE
Then the print function I have prints out the words correctly in the array but it includes all 30 spaces for each word instead of just the word. This is how it is written I need to change it.
void print(void *array, int SIZE){
int i,
j;
char *charArray = (char *) array;
for( j = 0; j < SIZE; j++ ){
for( i = 0; i < SIZE; i ++){
printf( "%c ", charArray[j*SIZE + i] );
}
printf( "\n" );
}
}
The tolower function I created was partially working converting the first letter of each word to lowercase. Now it is broke and do not remember what I have changed.
EDIT- updated lowercase function. The lowercase in main works exactly but with this function it doesn't convert all the words to lowercase it stops at the third word the rest are the same.
void lowercase(char *words, int count){
int j;
for(j = 0;j<cols;j++){
if(words[j]!=0){
if(words[j]<91 && words[j]>64)
words[j] = words[j]+32;
}
}
}
I tried to move the read code in main to its own function also trying to mimic the print code with the pointers but when I run the program it stalls and the exe file stopped working window pops up with command prompt.
No errors or warnings in IDE.
int read(void *array){
FILE *file;
int i,
j;
char *words = (char *) array;
file = fopen("words.txt", "r");
//STORE IN ARRAY
for(i=0;i<7;i++)
fscanf(file,"%s", words[i]);
}
If you have not figured out I have no idea when or how to use pointers or addresses. I have been taught basically all of C in literally 12 hours which is in my opinion not enough time to learn the language at all especially understand it efficiently. Any help will be greatly appreciated. Thank You.
By casting a 2-dimensional array down to a char*, you have lost some information. If you read the words in correctly, then in memory, your array might look like this:
0 10 20 30
|.........|.........|.........|.
There
ARE
so
MANY
words
in
HERE
To access words[1] the compiler is automatically offsetting 31 bytes from the beginning of the array.
Your problem is that after you cast words to char*, then the compiler no longer knows about the 2D structure, and words[1] will now only offset 1 byte from the beginning of the array.
A simple solution is to redefine your read function:
int read(char words[][31])
{
FILE *file;
int i, j, count = 0;
file = fopen("words.txt", "r");
for (i=0; i<7; i++)
{
count += (1 == fscanf(file, "%s", words[i]));
}
return count;
}
Now the compiler knows that the memory stride size for words[i] is 31 char values.
Similar thing with print:
void print(char words[][31], int count)
{
int i;
for( i = 0; i < count; i ++)
{
printf( "%s\n", words[i] );
}
}
fix like this:
#include <stdio.h>
#include <stdlib.h>
//Stringification
#define S_(n) #n
#define S(n) S_(n)
//Information to be shared across the whole area
#define MAX_ROWS 200
#define MAX_WORD_LENGTH 30
#define COLS (MAX_WORD_LENGTH + 1)
#define DATA_FILE "words.txt"
int read(void *array);
void print(void *array, int rows);
int main(void){
char words[MAX_ROWS][COLS];
int rows;
rows = read(words);
print(words, rows);
return 0;
}
int read(void *array){
FILE *file = fopen(DATA_FILE, "r");
if(file == NULL){
perror("fopen:");
exit(EXIT_FAILURE);
}
char *words = array;
int rows;
for(rows = 0; rows < MAX_ROWS; ++rows, words += COLS){
if(fscanf(file, "%" S(MAX_WORD_LENGTH) "s", words) == EOF)
break;
}
fclose(file);
return rows;
}
void print(void *array, int rows){
char *words = array;
for(int r = 0; r < rows; ++r, words += COLS){
printf("Array [%d]: %s\n\n", r, words);
}
}
How do you make 2 array strings into 1 array string, where I can print out all the 52 playing cards?
my code:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
int main() {
char deck[52];
char suits[] = {"Hearts","Diamonds","Clubs","Spades"};
char values[]= {"Ace","Two","Three","Four","Five","Six",\
"Seven","Eight","Nine","Ten","Jack",\
"Queen","King"};
int V, S, d = 0;
char string;
for ( S= 0; S <4; S++) {
for (V =0; V< 13; V++) {
string = strcat( values[V], suits[S]);
deck[d] = string;
printf("%s\n", string);//prints out all the 52 playing cards
d++;
}
}
return 0;
}
When I executed the program, the problem comes up which asks me to debug the program or close the program, where I closed the program in the end, which returns nothing. Can you please give me the answer which works?
Check the below code which fixes the issues in your code:
The problem with your code is you try to modify the actual string before printing and because of this there is a modified string in the next iteration. So just copy the values and suits to array and print it out as shown below.
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
int main()
{
int i=0;
char deck[30] = "";
char suits[][30] = {"Hearts","Diamonds","Clubs","Spades"};
char values[][30]= {"Ace","Two","Three","Four","Five","Six",
"Seven","Eight","Nine","Ten","Jack",
"Queen","King"};
int V, S;
for ( S= 0; S <13; S++)
{
for (V =0; V< 4; V++){
memset(deck,0,sizeof(deck));/* Clear the buffer before writing new value*/
strcpy( deck, values[S]);
strcat(deck,suits[V]);
printf("%s\n", deck);//prints out all the 52 playing cards
i++;
}
}
printf("Number of playing cards: %d\n",i);
return 0;
}
strcat() returns a char *, a pointer to a char, not a char.
You are not even required to even consider the return value of strcat() since the destination pointer (first argument) will now contain the concatenated string, assuming enough memory is already allocated.
So here in your code, you are trying to put the concatenated string to values[V] which could fail when memory already allocated to it becomes insufficient.
The best method would be to allocate some memory (as you did with deck[]) and set it all to zeroes. Then keep strcat()ing there.
strcat(deck, values[V]);
strcat(deck, suits[S]);
An alternative to using strcpy and strcat is to use sprintf.
#include<stdio.h>
#include<string.h>
#define NUM_SUITS 4
#define CARDS_PER_SUIT 13
#define TOTAL_CARDS (NUM_SUITS * CARDS_PER_SUIT)
int main()
{
char deck[TOTAL_CARDS][24];
char* suits[NUM_SUITS] = {"Hearts","Diamonds","Clubs","Spades"};
char* values[CARDS_PER_SUIT]= {"Ace","Two","Three","Four","Five","Six",
"Seven","Eight","Nine","Ten","Jack",
"Queen","King"};
int s, c, i;
for(s = 0; s < NUM_SUITS; s++)
{
for(c = 0; c < CARDS_PER_SUIT; c++)
{
sprintf(deck[(s * CARDS_PER_SUIT) + c], "%s of %s", values[c], suits[s]);
}
}
for(i = 0; i < TOTAL_CARDS; i++)
{
printf("%s\n", deck[i]);
}
return 0;
}
could everyone please help me what is wrong with my code or what is missing from my code...
We have this activity where we have to find the highest number using another function..
#include <stdio.h>
#include <stdlib.h>
#define p printf
#define s scanf
int high (int n1);
int main(int argc, char *argv[])
{
int i, num[10];
p("Input 10 numbers\n");
for (i=0; i<10; i++)
{
p("Enter Number: ");
s("%d",&num[i]);
}
p("Highest Number: %d",high(num[i]));
getch();
}
int high (int n1)
{
int l;
for (l=0; l<n1; l++)
{
if (n1 > l)
return n1;
}
}
When I input any number I always got 37..
int high (int n1); should be
int high (int *arr, int sz); /* You need to pass an array */
p("Highest Number: %d",high(num[i])); should be
p("Highest Number: %d",high(num, 10)); /* Passing array now, not one element */
int high() should be re-written as:
int high (int *arr, int sz)
{
int l, mx = INT_MIN;
for (l=0; l<sz; l++)
{
if (mx < arr[l])
{
/* Left as an excercise */
}
}
return mx;
}
As this is tagged c++, I would suggest using available C++ to find max in a range:
const int max = *std::max_element(&num[0], &num[10]); // #include <algorithm>
Well, I don't know if you still need an answer, but I corrected your code. Here are the mistakes I found
int high (int n1)
{
int l;
for (l=0; l<n1; l++)
{
if (n1 > l)
return n1;
}
}
In this for-loop, there is the condition l<n1 and inside the for loop you have the statement if(n1 > l) which will never be attained because of l<n1. You said you were getting 37 each time, but I was getting 10 instead. This shows it was undefined behavior because no real value was returned. ( This code part really didn't mean any sense either as this function doesn't even try to find the largest number ).
Another issue I found is you have used getch() without including <conio.h> ( Also pointing out that <conio.h> is not standard in C++ )
Well, even though this question is tagged C++, since the code is completely c, I have made a fixed code in c. I've removed getch() in the code. So here is the code
#include<limits.h>
#include <stdio.h>
#include <stdlib.h>
#define p printf
#define s scanf
int high (int *n1,int lar); // now I have used *n1 to get the address of the array.
int main(int argc, char *argv[])
{
int i, num[10],lar=INT_MIN; // the variable lar is given the minimum value that can be held by an int
p("Input 10 numbers\n");
for (i=0; i<10; i++)
{
p("Enter Number: ");
s("%d",&num[i]);
}
p("Highest Number: %d",high(num,lar)); // sending the entire array to the function by sending its address
}
int high (int *n1,int lar)
{
int l;
for (l=0; l<10; l++) // since the size you have taken for your array is 10, I have used 10 here. But if you don't know the size beforehand, pass the size as an argument to the function
{
if (n1[l] >lar ) // Well, this is the simple part
lar=n1[l]; // Simply assigning the largest value to lar
}
return lar; // Finally returning the value lar.
}
Well, hope this helps you.
This C program reads a line of text from keyboard and then writes the longest word in the line. The issue with my code below is that it only prints the last word apart from its length, although everything seems fine. Can anyone see a problem with my code?
#include<stdio.h>
#include<string.h>
#define MAX 132
#define MAXW 30
int Len_w[MAXW];
int Max_V(int vf[], int len);
main()
{
char s[MAX+1], w[MAXW], *Ind_w[MAXW],*p,out[MAXW];
int k=0, i=0, Maximum, g=0;
printf("\nInsert the line....\n");
p=fgets(s, MAX, stdin);
while(sscanf(p, "%s%n", w, &k)==1){
Len_w[i] = strlen(w);
Ind_w[i] = w; //the issue is here!!
p+=k+1;
i++;
}
Maximum = Max_V(Len_w,i);
for(g=0;g<i;g++){
if(Len_w[g] == Maximum){
//sscanf(Ind_w[g],"%s",out);
printf("\n%s", Ind_w[g]);
}
}
return 0;
}
/*----------------------------------------------------------------------------*/
int Max_V(int vf[], int len)
{
int j; int Max;
Max=*vf;
for(j=1; j < len; j++)
{
if(*(vf+j) > Max)
{
Max=*(vf + j);
}
}
return Max;
}
/*----------------------------------------------------------------------------*/
Ind_w[i] = w;//the issue is here!!
You let all pointers in Ind_w point to the same buffer, which is overwritten for each entered word. So only the last entered word remains "visible".
If you have it,
Ind_w[i] = strdup(w);
is a simple solution. Otherwise
Ind_w[i] = malloc(strlen(w)+1);
strcpy(Ind_w[i], w);
Both ways require the pointed-to memory to be freed when it is no longer used.
Ind_w[i] = strdup(w);//the issue is here!!
You have to duplicate the w buffer each time you read the buffer and not use the same buffer for all reading. with the way you did you will have all the array elements pointing to the same buffer and this buffer is containing the same string which is the last one read with sscanf
Note: you have to free all the duplicated buffers when they come useless. You can do it by go over the array of pointers and free each element (pointer)
I'm trying to pass a 2D array with strings in it into a function. I keep getting the
expected expression before ] token.
The point of this code is to read in a wordsearch puzzle, then find the words in that puzzle. I'm going to be writing a function for forward search, backword search, and then up and down search.
How do I get rid of this error? The error is down at the very bottom where I call the forward function.
/*Andrea Hatfield CPE 101 October 31st, 2012*/
#include <stdio.h>
#include <string.h>
int forward(char words[][8], char puzzle[][11]);
int main()
{
char puzzle[11][11];
char words[8][8];
FILE *fin, *fwords;
int i = 0;
int j= 0;
fin = fopen("puzzle.in", "r");
fwords = fopen("words.in", "r");
if(fin == NULL) /*Reads in the puzzle file*/
printf("File does not exist");
else
{
while(fscanf(fin,"%s", puzzle[i])!=EOF)
{
printf("%s\n", puzzle[i]);
i++;
}
}
if(fwords == NULL) /*Reads in the words the puzzle will search for */
printf("File does not exist");
else
{
while(fscanf(fwords, "%s", words[j])!=EOF)
{
printf("%s\n", words[j]);
}
}
forward(&words[][8], &puzzle[][11]); /*Error at this point*/
return(0);
}
It is a little bit hard to get what you want to do but there is a problem in here:
forward(&words[][8], &puzzle[][11]);
try this instead:
forward(words, puzzle);
Here are two other options that should be mentioned from here:
#define ROWS 4
#define COLS 5
void func(int array[ROWS][COLS]) {
int i, j;
for (i=0; i<ROWS; i++) {
for (j=0; j<COLS; j++) {
array[i][j] = i*j;
}
}
}
void func_vla(int rows, int cols, int array[rows][cols]) {
int i, j;
for (i=0; i<rows; i++) {
for (j=0; j<cols; j++) {
array[i][j] = i*j;
}
}
}
int main() {
int x[ROWS][COLS];
func(x);
func_vla(ROWS, COLS, x);
}
You need to call directly
forward(words, puzzle);
However, you have an error in your code: you forgot the j++ in the reading cycle while reading words, so you are overwriting words[0] and not initialising the other members of the array.
Also, in a real world situation, you might find it desirable to choose the array size at run time. A simple way to do it would be to choose a reasonably large limit for both width and height, and go with 0x90's solution (you need a 30x20 puzzle, and you can handle it easily since you compiled with ROWS and COLS equal to, say, 1024).
A more complicated way would be to use malloc() (using pointers to pointers to chars) and allocate both arrays dynamically, limited by available memory; you would then pass their dimensions to the forward function.
int forward(char **words, char **puzzle, size_t w_w, size_t w_h, size_t p_w, size_t p_h)
{
}
Yet, the allocation part would be more complicated given the looped calls to malloc() and the need to check its return value every time to intercept out-of-memory conditions; also, in some scenarios you might want the memory to be deallocated (e.g. to run repeated puzzles), which leads to further complexity.