C multidimensional array , can't see what's wrong - c

The program needs you to enter the number of lines and columns (m and n) , enter elements into the array, then specifiy an element to be found and find it.
Once you do , print the position found at (starting with 1) , the line and column index, also specify the number of times the element was found.
The problems with my program : it prints several times bad numbers before the final printf that shows the correct location. If the location of the searched is at the start it shows nothing. I tested with printf the second for loop and saw that it only displayed the last 2 elements entered into the array.
Another problem is that i get an error anytime i try to enter a array that is bigger than [2] [2] , for example [3][3].
#include <stdio.h>
#include <stdlib.h>
main()
{
int m=0,n=0,tablou[m][n],i,j,e,nr=0,poz=0;
printf("Introduceti nr. de linii si nr. de coloane");
scanf("%d %d",&m,&n);
printf("Introduceti elementele in tablou\n");
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
scanf("%d",&tablou[i][j]);
}
}
printf("Introduceti elementul pe care vreti sa-l gasiti");
scanf("%d",&e);
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
poz++;
if(tablou[i][j]==e)
{
printf("Elementul a fost gasit la pozitia %d fata de elementul 1, pe linia %d si coloana %d",poz,i+1,j+1);
nr++;
}
}
}
if(nr>0)
{
printf("\nElementul a fost gasit de %d ori",nr);
}
}
I can't see what's wrong, any help would be appreciated , thank you.

You should declare the array after initializing n and m to non-zero values, something like this
int m, n;
if (scanf("%d%d", &n, &m) != 2)
{
/* you could write a function that tries to get input again */
printf("invalid input\n");
return -1;
}
int tablou[m][n];
also not that main() should return int.

#iharob uses the new dynamc arrays of C99. It is a nice feature with the compiler doing lots of things for you. In older chainsaw versions of C you have to do that yourself:
int m, n, *tablou;
if (scanf("%d%d", &n, &m) != 2)
{
printf("invalid input\n");
return -1;
}
if ((tablou= calloc(n*m, sizeof(int)))==NULL) return -1;
...
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
poz++;
if(tablou[ i*n + j]==e)
...

Related

I Want to add the numbers in the matrix

I want the sum of the numbers in the matrix in each column to add up, tried doing this using different variation's of the same music[i+1][j]+=music[i][j], but its not working, so basically what the program does, it assigns 3 points to the first number the user inputs as his favorite song, the second song get 2 points and the third 1 point, i want the matrix at the end to sum up all the points from the participants and give me the total.
#include <stdio.h>
#include <stdlib.h>
int main()
{ int num=0, pers=0;
int i,j, k;
int votos=0;
printf("Digite la cantidad de personas:");
scanf("%d", &pers);
float music[pers+1][10];
for(i=0;i<pers+1;i++){
for(j=0;j<10;j++){
music[i][j]=0;
}
}
for(i=0;i<pers;i++){
printf("Participante %d :\n",i+1);
for(k=1;k<=3;k++){
printf("Digite el numero de sus 3 canciones favoritas %d:\n",k);
scanf("%d",&num);
for(j=0;j<9;j++){
if (k==1){
music[i][num-1]=3;
}
if (k==2){
music[i][num-1]=2;
}
if (k==3){
music[i][num-1]=1;
}
music[10][j]+=music[i][j];
}
}
}
for(i=0;i<pers+1;i++){
for(j=0;j<10;j++){
printf("%.2f\t",music[i][j]);
}
printf("\n");
}
return 0;
}
GDB is your friend for these sorts of problems. You can install an interactive debugger and step through your code line by line to see what values your matrix takes on certain input.
If you did that, you may have saw that you're accessing the 10th row of your matrix. Even if pers is initialized to three.
There's also an issue where you begin summing music values as they're being initialized (leading to over counting).
for (i = 0; i < pers; i++)
{
printf("Participante %d :\n", i + 1);
for (k = 1; k <= 3; k++)
{
printf("Digite el numero de sus 3 canciones favoritas %d:\n", k);
scanf("%d", &num);
if (k == 1)
{
music[i][num - 1] = 3;
}
if (k == 2)
{
music[i][num - 1] = 2;
}
if (k == 3)
{
music[i][num - 1] = 1;
}
}
}
for(j = 0 ; j < 10; j++)
{
for (i = 0; i < pers+1; i++)
music[pers][j] += music[i][j];
}
I'm hoping this code doesn't fully solve your problem since it'll be good for you to look into gdb and learn how to interact with your code and understand where its deviating from your expectations.
It'll also help to do as paddy suggested and explain what your input and output is supposed to look like.
Try This Code It working and sum up
#include <stdio.h>
#include <stdlib.h>
int main(){
int num=0, pers=0;
int i,j, k;
int votos=0;
printf("Digite la cantidad de personas:");
scanf("%d", &pers);
float music[100][100];
float sum[100][100];
for(i=0;i<pers+1;i++){
for(j=0;j<10;j++){
music[i][j]=0;
}
}
for(i=0;i<pers;i++){
printf("Participante %d :\n",i+1);
for(k=1;k<=3;k++){
printf("Digite el numero de sus 3 canciones favoritas %d:\n",k);
scanf("%d",&num);
for(j=0;j<9;j++){
if (k==1){
music[i][num-1]=3;
}
if (k==2){
music[i][num-1]=2;
}
if (k==3){
music[i][num-1]=1;
}
sum[i][j]+=music[i][j];
}
}
}
for(i=0;i<pers+1;i++){
for(j=0;j<10;j++){
printf("%.2f\t",sum[i][j]);
}
printf("\n");
}
return 0;
}

Sorting inputted integers into odd and even arrays

I'm a beginner to C, and am trying to sort user inputted numbers into odd and even arrays. I don't understand why my code isn't working.
Cheers.
This is my code, I don't understand my mistake.
int x[]= {};
int i=0;
int d=0;
int j=0;
int even[12]={};
int odd[12]={};
printf("Enter amount of numbers: "); // asking user for amount of numbers
scanf("%d", &d);
for (j=0; j<d; j++){
printf("Enter number %d: ", i+1); // scanning input into 'x' array
scanf("%d", x[i]);
}
printf("Even numbers: ");
for (i=0; i<d; i++) {
if (x[i] % 2 == 0) { // sorting into even array
even[i]=x[i];
printf("%d \n", even[i]);
}
}
printf("\n Odd numbers: ");
for (i=0; i<d;i++){
if (x[i] % 2 != 0) { // sorting into odd array
odd[i]=x[i];
printf("%d \n", odd[i]);
}
}
This error message keeps coming up:
$ ./main
Enter amount of numbers: 4
Enter number 1: 6
Segmentation fault (core dumped)
int x[]= {}; doesn't work because it would hold no elements. But initializing it with {} doesn't work in C anyway, do this instead:
int x[24] = {0}; // first element explicitely set to 0, the rest default-initialized to 0
You also need to put {0} for even and odd. If it's compiling for you with {} then it's possible that you're compiling it as a C++ program, or perhaps your compiler just tolerates it anyway (but it won't work on every C compiler).
scanf needs the address of the int, so instead of scanf("%d", x[i]); you need scanf("%d", &x[i]);. But i is the wrong iterator for this for (j = 0; j < d; j++) loop. Instead do this:
for (j = 0; j < d; j++) {
printf("Enter number %d: ", j + 1); // scanning input into 'x' array
scanf("%d", &x[j]);
}
Also note that the way you're doing this, half the array will be left at 0. So for instance if I imputted the values 1 through 6, then odd contains the values 1 0 3 0 5 0.

Strange error while adding a feature to my little game (0xC0000005)

Hello everyone,
I decided some time ago to write my own version of Minesweepers as some practice and I did it. The game ran perfectly, but after deciding to add a "Choose difficulty" option the window freezes and I get an error message, saying that the program does not respond. Also the line 0xC0000005 appeares. I have tryed many, many things: moving code from main() to a seperate function(now all in int playGame()), allocating some more memory in the heap, even creating a seperate .c file to store some piece of the code, but nothing worked sofar. I came back to the code after a few weeks, but I still have no clue why it is happening.
Can anyone help me with this? I hope my code is not hard to read. I added some comments explaining what is what. I am still new to C.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "difLvl.c"
int displayFiled(char **field); //prints out the map of the field
int combine(char answer, int answer1); //combines user input and field numeration
int Randomizer(int **mineArray); //generates random mine map
int difficulty();
int playGame();
int main(){
int playGame();
playGame();
system("PAUSE");
return 0;
}
int Randomizer(int **mineArray){
int difficulty();
int i, j;
srand(time(NULL));
int mines;
int placeMine;
int totalMines;
//int difLvl=2;
int difLvl=difficulty();
for(i=0, totalMines=0; i<10; i++){
for(j=0, mines=0; j<10 && mines<difLvl; j++){
placeMine= rand() % 2;
mineArray[i][j] = placeMine;
if(placeMine==1){
++mines;
};
};
totalMines+=mines;
};
return totalMines;
}
int displayFiled(char **field){
int i, j;
printf(" A B C D E F G H I J\n");
printf(" --------------------\n");
for (i=0; i<10; i++){
if (i==9){
printf("%d |", i+1);
}else{
printf("%d |", i+1);
};
for (j=0; j<10; j++){
printf("%c ", field[i][j]);
if (j==9){
printf("\n");
};
};
};
printf("\n");
return 0;
}
int playGame(){
int displayFiled(char **field);
int combine(char answer, int answer1);
int Randomizer(int ** mineArray);
char Y_char; //column as character (a, b, c etc.)
int X; //row
int Y; //Y_char converted to a number
int **mineArray; //stores the map of mines
char **fieldDisplay; //prints out the map of the field
int i, j; //counters
int life=1;
int movePl=0; //no dying on the first move
int globalMines; //number of mines placed
int openedFields=0; //counts the number of fields opened
//int difLvl;
//int difficulty();
//difLvl= difficulty();
/*disabled the trhee lines above while I was trying some solutions*/
/*int difficulty() is now called from int Randomizer()*/
system("cls");
/*Allocates memory to mineArray*/
mineArray= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
mineArray[i] = calloc(10, sizeof(int));
};
/*Allocates memory to fieldDisplay*/
fieldDisplay= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
fieldDisplay[i] = calloc(10, sizeof(int));
};
/*default look of fields with ?*/
for (i=0; i<10; i++){
for (j=0; j<10; j++){
fieldDisplay[i][j]='?';
};
};
globalMines= Randomizer(mineArray);
while(life==1 && openedFields<(100-globalMines)){
/*for checking purposes only*/
/*for (i=0; i<10; i++){
for (j=0; j<10; j++){
printf("%d ", mineArray[i][j]);
if (j==9){
printf("\n");
};
};
};*/
//printf("\nDifficulty level %d\n", difLvl);
printf("Total number of mines is %d\n\n", globalMines);
printf("\tMove nr. %d\n\n", movePl+1);
displayFiled(fieldDisplay);
printf("Which field do You want to activate?\nType first the letter, space and then the number (A 1, B 10 etc.)\n");
scanf("%c %d", &Y_char, &X);
if (Y_char >= 'A' && Y_char <= 'Z'){
Y = Y_char - 'A';
}else if(Y_char >= 'a' && Y_char <= 'z'){
Y = Y_char - 'a';
};
/*checks if a field is a mine*/
/*X-1 because the player chooses from 1 to 10*/
if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='?'){
movePl++;
fieldDisplay[X-1][Y]='0';
openedFields=openedFields+1;
OPEN : if (((X-2)<10) && ((X-2)>=0)){
if (mineArray[X-2][Y]==0 && fieldDisplay[X-2][Y]=='?'){
fieldDisplay[X-2][Y]='0';
openedFields=openedFields+1;
};
};
if ((X<10) && (X>=0)){
if (mineArray[X][Y]==0 && fieldDisplay[X][Y]=='?'){
fieldDisplay[X][Y]='0';
openedFields=openedFields+1;
};
};
if (((Y+1)<10) && ((Y+1)>=0)){
if (mineArray[X-1][Y+1]==0 && fieldDisplay[X-1][Y+1]=='?'){
fieldDisplay[X-1][Y+1]='0';
openedFields=openedFields+1;
};
};
if (((Y-1)<10) && ((Y-1)>=0)){
if (mineArray[X-1][Y-1]==0 && fieldDisplay[X-1][Y-1]=='?'){
fieldDisplay[X-1][Y-1]='0';
openedFields=openedFields+1;
};
};
system("cls"); //clears console screen
}else if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='0'){
system("cls");
printf("You can't choose an already opened field!\n\n");
}else if(mineArray[X-1][Y]==1 && movePl==0){
/*only activates on the first turn if players hits mine*/
movePl++;
mineArray[X-1][Y]= 0;
fieldDisplay[X-1][Y]='0';
globalMines=globalMines-1;
goto OPEN;
system("cls");
}else{
system("cls");
printf("YOU DIED ! YOU DIED ! YOU DIED !\n\n");
printf("Moves successfully made: %d\n\n", movePl-1);
fieldDisplay[X-1][Y]='1';
displayFiled(fieldDisplay);
--life;
};
};
if(openedFields==(100-globalMines)){
printf("Congratulations! You won the game!\n\n");
displayFiled(fieldDisplay);
};
for(i = 0; i < 10; i++){
free(mineArray[i]);
};
free(mineArray);
for(i = 0; i < 10; i++){
free(fieldDisplay[i]);
};
free(fieldDisplay);
return 0;
}
The difLvl.c file:
#include <stdio.h>
#include <stdlib.h>
int difficulty(){
int difLvl;
while(1){
printf("Please choose a difficulty level:\n");
printf("Easy-1\nNormal-2\nNightmare-3\n");
printf("Your answer: ");
scanf(" %d", &difLvl);
if(difLvl>=1 && difLvl<=3){
break;
}else{
system("cls");
continue;
};
};
system("cls");
return difLvl;
}
I created it, because I thought that maybe main() had too many code in it and that maybe that was why the difficulty option wasnt working right.
EDIT
After the user is promped to enter the difficulty level, the mine map is created, but after choosing a filed, the program crashes.
SOLVED
scanf("%c %d", &Y_char, &X);
changed to
scanf(" %c %d", &Y_char, &X);
First, you don't allocate your two-dimensional fields correctly. The "outer" field must hold int *, not just int:
mineArray = calloc(10, sizeof(*mineArray));
for (i = 0; i < 10; i++) {
mineArray[i] = calloc(10, sizeof(*mineArray[i]));
}
Another potential source of the segmentation fault is that Y might end up uninitialised and therefore with a garbage value. The cause is the scanf:
scanf("%c %d", &Y_char, &X);
Most scanf formats skip white space before the conversion, but %c doesn't. It is very likely that you read the newline character as the char for %c when you expect to read a letter. Because the new-line character is white space, you can hot-fix the by placing a space before the %c? format:
scanf(" %c %d", &Y_char, &X);
(I say hot-fix, because it isn't a good solution. scanf doesn't treat new-line characters specially; they are just space. A better solution might be to read a line first with fgets and then scan that with sscanf. At least you can treat each line as frash input. (And your input really should ensure that bad input is ignored.)
Lastly, it is strange that you include a *.c file. If you want to spread ypur project over various files, which is basically a good idea, you should write a header file for each *.c, which has the file's interface. Include the header files in other *.c files; compile the *.c files into objects separately and then link them. This process is usually controlled by Makefiles or Projects.

Trouble storing the size of each array I have in C

I'm having trouble storing the size of each array the user inputs. I need to do this so that I can run different calculations on each set. This is what I'm trying to do now, but it keeps throwing a segmentation fault, and I don't know what I'm doing wrong. The other thing I thought of doing was essentially make one more memory spot with malloc and just store the sizes in another array at the end of the data set arrays. Anyway, here's the code that is giving me a segmentation fault.
int construct_data_sets(int *sets[], int count) {
int set_size;
int j;
j = 0;
printf("Enter the number of elements in data set %d: ", count+1);
scanf(" %d", &set_size);
sets[count] = (int*)malloc((sizeof(int) * set_size));
if (sets[count] == NULL){
printf("Malloc failed!\n");
}
printf("Enter the data for set %d: ", count+1);
while ((j + 1) <= set_size)
{
scanf(" %d", &sets[count][j]);
j++;
}
return set_size;
}
And here's the main, I think the segmentation fault gets thrown when I call construct_data_sets().
int main() {
int command = 0, data_set, set_desired, array_size;
int number = prompt_num_sets();
int *sets[number], i = 0, *sizes[number];
while (i < number)
{
array_size = construct_data_sets(sets, i);
*sizes[i] = array_size;
i++;
}
//printf("The size of the 3rd data set is %d", *sizes[3]);
printf("Data at [data_set][1] = %d\n", sets[data_set-1][1]);
set_desired = select_data_set(number);
while (command != 7) {
printf("Choose what you would like to do:\n");
printf("1. Find the minimum value.\n");
printf("2. Find the maximum value.\n");
printf("3. Calculate the sum of all the values.\n");
printf("4. Calculate the average of all the values.\n");
printf("5. Sort the values in ascending order.\n");
printf("6. Select a different data set.\n");
printf("7. Exit the program.\n");
scanf(" %d", &command);
if (command == 7) {
exit_program();
} else if (command == 6) {
change_term(number, sets);
}
printf("====================================\n");
}
}
Any weird printf statements you may see are just me trying to make sure things are doing what they're supposed to. Let me know if you need more information from me. Thanks.
You have multiple bugs in your code and several stylistic issues. Have you tried running the code in the debugger to see exactly where things are crashing? Have you tried narrowing the code down to a smaller problem?
Your sizes array should have an element type of int instead of int *. You are dereferencing uninitialized memory since you have not allocated anything for the pointers. Your data_set variable is also uninitialized so the array access into sets is also undefined.
You should initialize all of your variables immediately upon definition. Also I would change your code to declare only one variable per statement. The current code is quite difficult to read.
I would also change your initial while loop into a for loop.
Here's a working version that doesn't crash; although, since you haven't included all of the code, I don't know if there are other parts that are broken. I've also had to remove the references to the undefined functions:
#include <stdio.h>
#include <stdlib.h>
int construct_data_sets(int *sets[], int count) {
int set_size;
int j;
printf("Enter the number of elements in data set %d: ", count+1);
scanf(" %d", &set_size);
sets[count] = (int *) malloc((sizeof(int) * set_size));
if (sets[count] == NULL) {
fprintf(stderr, "Malloc failed!\n");
exit(-1);
}
printf("Enter the data for set %d: ", count+1);
for (j = 0; j < set_size; ++j) {
scanf(" %d", &sets[count][j]);
}
return set_size;
}
int main(int argc, char *argv[]) {
int command = 0;
int number = 1;
int *sets[number], i, sizes[number];
for (i = 0; i < number; ++i) {
sizes[i] = construct_data_sets(sets, i);
}
printf("Data at [0][1] = %d\n", sets[0][1]);
while (command != 7) {
printf("Choose what you would like to do:\n");
printf("1. Find the minimum value.\n");
printf("2. Find the maximum value.\n");
printf("3. Calculate the sum of all the values.\n");
printf("4. Calculate the average of all the values.\n");
printf("5. Sort the values in ascending order.\n");
printf("6. Select a different data set.\n");
printf("7. Exit the program.\n");
scanf(" %d", &command);
if (command == 7) {
return 0;
} else if (command == 6) {
return 0;
}
printf("====================================\n");
}
return 0;
}

C program with two dimensional arrays?

in a two dimensional array there are kept the working hours for N workers and M projects,the names of the workers are kept in an array with the name Worker and the name of the projects in an array with the name "Project".Write a program which reads the data and displays the worker with more working hours.So I tried this,but everytime I ran it,it seems to be a logical error,because it says :Give the number of the project,and If I type "2" this is also the number of the workers according to my program,and then it asks for the hours for each worker..
#include<stdio.h>
#include<conio.h>
int main()
{
int i, j, n, worker[100][10], hours[30][100];
printf("The number of the project: ");
scanf("%d", &n);
for (i=0; i<n; i++)
{
printf("Give the worker %d: ", i+1);
scanf("%s", &worker[i]);
}
for (i=0; i<n; i++)
{
printf("\n The worker %s\n", worker[i]);
for (j=0; j<30; j++)
{
printf("The number of the hours for the day %d: ", j+1);
scanf("%d", &hours[i][j]);
}
}
for (i=0; i<n; i++)
{
for (j=0; j<30; j++)
if (hours[i][j]==0)
break;
if (j==30)
printf("%s\n", worker[i]);
}
getch();
return 0;
}
You seem to be taking the input incorrectly.
scanf("%s", &worker[i]);
worker is a 2D array of type int. So, you need to have another index while taking input. Also the format specifier for int is %d. Any decent compiler should have given you warnings during compilation.
Seems to me that you first must ask how many workers (N) and how many projects (M) with something like:
int ii, m, n;
char **worker;
char **project;
printf("How many workers? ");
scanf("%d", &n);
printf("How many projects? ");
scanf("%d", &m);
Then ask for the names of the workers:
// Allocate space for n worker string pointers
worker = (char **)malloc(n * sizeof(char *));
for (ii = 0; ii < n; ++ii)
{
char bufname[1024]; // danger here if input too long
printf("Name of worker[%d]? ", ii + 1);
scanf("%s", bufname);
worker[ii] = strdup(bufname);
}
Then ask for the names of the projects, similarly. Then get the hours, then calculate the max, then free up the dynamically allocated worker & project strings (and the two array of pointers).

Resources