[EDITED]I wrote a program in C and it should print a vertical wave by printing and modifying the vector "riga_disegno" continously.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int riga_disegno[10], i = 0, j = 0, k = 0, length = 0;
for(i = 0; i < 10; i++) /* Inizializza il vettore */
{
riga_disegno[i] = 177;
}
printf("Quanti periodi dell'onda vuoi stampare?");
scanf("%d", &length);
for(k = 0; k < length; k++)
{
for(j = 0; j < 10; j++) /* Assegna ad un componente vettore il disegno dell'onda */
{
riga_disegno[j] = 254;
for(i=0; i < 10; i++)
{
putchar(riga_disegno[i]); /* stampa il carattere [i] del vettore*/
}
printf("\n");
riga_disegno[j] = 177; /* Riporta il componente al carattere di base */
Sleep(100);
}
for(j = 9; j >= 0; j--) /* Assegna ad un componente vettore il disegno dell'onda */
{
riga_disegno[j] = 254;
for(i=0; i < 10; i++)
{
putchar(riga_disegno[i]);
}
printf("\n");
riga_disegno[j] = 177; /* Riporta il componente al carattere di base */
Sleep(100);
}
}
return 0;
}
I entered the function Sleep because the execution of the program was too fast, but now, when I compile it prints strange characters near the "wave".
Thank you.
Sorry for my bad english, I'm italian.
Your code invokes undefined behaviour when you modify riga_disegno beyond its boundaries. You access and modify riga_disegno[-1] and riga_disegno[10]. As explained, undefined behaviour means anything can happen, including expected behaviour.
In your particular case, you wonder why the behaviour changes when you modify your code by adding function calls Sleep(). A possible explanation is that the compiler generates different code when you modify the source, especially when you invoke external functions. The side effects of modifying memory beyond array boundaries may be different because the array riga_disegno itself or the other local variables i and j may be allocated differently. Without the calls, the side effect might not affect the program's output, leading you to erroneously believe that everything works fine. With the calls, you can see some side effects of this undefined behaviour.
This is a good illustration for why one should always avoid undefined behaviour. Even if the program seems to function properly, the slightest modification can have catastrophic consequences.
Related
So I have a 2D array that I want to use later. Right now I just want to fill the empty spots.
So far I've just been messing around with array types and different default values. From my understanding a new array is filled with '0', I have tried NULL aswell.
int r = 5;
int c = 5;
int i;
int j;
int k = 0;
int area = r*c;
const char *array[r][c]; //tried char array[r][c] and other types
Setup my initial values and array here.
while(k< area){
for (j = 0; j < c; j++){
for (i = 0; i<r; i++){
if (array[i][j] == 0){
board[i][j] = ".";
}
printf("%c",aray[i][j]);
if (i = r - 1){
printf("\n");
}
k++;
}
}
}
This is where I try replacing all non filled values (all of them at this point) with ".", so the output should be a row of 5x5 dots. Instead I get weird letters and numbers. I have tried %s insead of %c, and no luck there but the output was different. Where I do %s I get some dots, but still not on a grid and the weird values show up.
Also Im pretty sure printf in a for loop, by default does it on a new line so I won't get the grid, so is there a better way of doing this?
What you have is an array of pointers. This would be suitable for a 2D array of strings, but not for a 2D array of characters. This isn't clear from your question, so I'll assume that you actually want a 2D array of characters. The syntax is: char array [r][c];.
Notably, since you used r and c which are run-time variables, this array is a variable-length array (VLA). Such an array cannot be placed at file scope ("global"). Place the array inside a function like main().
In order to use VLA you must also have a standard C compiler. C++ compilers and dinosaur compilers won't work.
Since you will have to declare the VLA inside a function, it gets "automatic storage duration". Meaning it is not initialized to zero automatically. You have to do this yourself, if needed: memset(array, 0, sizeof array);. But you probably want to initialize it to some specific character instead of 0.
Example:
#include <stdio.h>
#include <string.h>
int main (void)
{
int r = 5;
int c = 5;
char array [r][c];
memset(array, '#', sizeof array);
for(size_t i=0; i<r; i++)
{
for(size_t j=0; j<c; j++)
{
printf("%c", array[i][j]);
}
printf("\n");
}
}
Output:
#####
#####
#####
#####
#####
From my understanding a new array is filled with '0'
const char *array[r][c];
No*, you have fill it yourself in a double for loop, like this:
for(int i = 0; i < r; ++i)
for(int j = 0; j < c; ++j)
array[i][j] = 0
since your structure is a variable sized array.
Instead I get weird letters and numbers
This happens because your code invokes Undefined Behavior (UB).
In particular, your array is uninitialized, you then try to assign cells to the dot character, if their value is already 0.
Since the array is not initialized, its cells' values are junk, so none satisfied the condition of been equal to 0, thus none was assigned with the dot character.
You then print the array, which still contains garbage values (since it was never really initialized by you), and the output is garbage values.
* As stated by #hyde, this is true for local non-static arrays (which is most probably your case). Statics and globals are default initialized (to zero if that was the case here).
You have several problems:
You are declaring a pointer to the array you want, not the array
Whenever R and C are not compile time known, you can't use a built in array. You might can however use VLAs (C99 as only C standard has VLAs mandatory, C11 made them optional again), which seems like a built in array with a size not known at compile time, but has very important implications, see : https://stackoverflow.com/a/54163435/3537677
Your array is only zero filled, when declared as a static variable.
You seem to have mistake the assign = operator with the equal == operator
So by guessing what you want:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define R 5
#define C 5
int r = R;
int c = C;
int i;
int j;
int k = 0;
int area = R*C;
const char array[R][C];
int main() {
while(k< area){
for (j = 0; j < c; j++){
for (i = 0; i<r; i++){
if (array[i][j] == 0){
}
printf("%c",array[i][j]);
if (i == r - 1){
printf("\n");
}
k++;
}
}
}
//or
char** dynamic_array = malloc(r * c);
if (dynamic_array == NULL) {
perror("Malloc of dynamic array failed");
return EXIT_FAILURE;
}
memset(dynamic_array, '0', r*c);
k = 0;
while(k< area){
for (j = 0; j < c; j++){
for (i = 0; i<r; i++){
if (dynamic_array[i][j] == 0){
}
printf("%c",dynamic_array[i][j]);
if (i == r - 1){
printf("\n");
}
k++;
}
}
}
return 0;
}
I am trying to implement Insertion sort algorithm in C.
But all I get is SIGSEGV error in online IDEs and the output doesn't show up in Code::Blocks. How to avoid Such errors.
#include <stdio.h>
#include <stdlib.h>
int main()
{
/* Here i and j are for loop counters, temp for swapping
count for total number of elements,array for elements*/
int i, j, temp, count;
printf("How many numbers are you going to enter");
scanf("%d", &count);
int n[20];
printf("Enter %d elements", count);
// storing elements in the array
for(i = 0; i < count; i++) {
scanf("%d", n[i]);
}
// Implementation of insertion sort algorithm
for(i = 0; i < count; i++) {
temp = n[i];
j = i - 1;
while(temp < n[j]) {
n[j+1] = n[j];
j = j - 1;
}
n[j+1] = temp;
}
printf("Order of sorted elements");
for(i = 0; i < count; i++) {
printf("%d", n[i]);
}
return 0;
}
There are a couple of problems with your code. First of all, what is a SIGSEGV error? Well, it's another name for the good old Segmentation fault error, which is basically the error you get when accessing invalid memory (that is, memory you are not allowed to access).
tl;dr: change scanf("%d",n[i]); to scanf("%d",&n[i]);. You're trying to read the initial values with scanf("%d",n[i]);, this raises a segmentation fault error because scanf expects addresses in which put the values read, but what you're really doing is passing the value of n[i] as if it were an address (which it's not, because, as you did not set any value for it yet, it's pretty much just memory garbage). More on that here.
tl;dr: change int n[20]; to int n[count]. Your array declaration int n[20]; is going to store at most 20 integers, what happens if someone wants to insert 21 or more values? Your program reserved a certain stack (memory) space, if you exceed that space, then you're going to stumble upon another program's space and the police (kernel) will arrest you (segmentation fault). Hint: try inserting 21 and then 100 values and see what happens.
tl;dr: change for(i = 0; i < count; i++) { to for(i = 1; i <= count; i++) {. This one is a logic problem with your indexes, you are starting at i = 0 and going until i = count - 1 which would be correct in most array iteration cases, but as j assumes values of indexes before i, you need i to start from 1 (so j is 0, otherwise j = -1 in the first iteration (not a valid index)).
My final code is as follows. Hope it helped, happy coding!
#include <stdio.h>
#include <stdlib.h>
int main() {
/*Here i and j are for loop counters,temp for swapping
count for total number of elements,array for elements*/
int i, j, temp, count;
printf("How many numbers are you going to enter?\n");
scanf("%d",&count);
int n[count];
printf("Enter %d elements\n",count);
//storing elements in the array
for(i = 0; i < count; i++) {
scanf("%d", &n[i]);
}
//Implementation of insertion sort algorithm
for(i = 1; i <= count; i++) {
temp = n[i];
j = i-1;
while(temp < n[j]) {
n[j+1] = n[j];
j--;
}
n[j+1] = temp;
}
printf("Order of sorted elements\n");
for(i = 0; i < count; i++) {
printf("%d\n",n[i]);
}
return 0;
}
Edit: If you're having trouble with online IDEs, consider running your programs locally, it saves a lot of time, plus: you never know what kernel version or magic the online IDEs are using to run your code (trust me, when you're coding in C -- fairly low level language, these things make a difference sometimes). I like to go all root style using Vim as text editor and gcc for compiling as well as gdb for debugging.
I wrote a brief piece of code. It has two functions: bubbleSort is a bubble sorting function (smallest to largest), and "int main" is used to test this piece of code with an int array of size 5.
I'd like this to destructively sort the array, and not simply pass through a copy. I have looked and looked, but I am still not entirely clear how this should work. What am I missing here?
#include <stdio.h>
void bubbleSort(int values[], int n);
int main(void) {
//set simple test array to make sure bubbleSort works
int arr[5] = {5,4,3,2,1};
//run it through function, and then print the now sorted array to make sure
bubbleSort(arr, 5);
printf("%i", arr);
return 0;
}
void bubbleSort(int values[], int n)
{
for (int i = 0; i < n; i++) {
for (int j = 0, hold = 0; j < n-i; j++) {
if (values[j] > values[j+1]) {
hold = values[j+1];
values[j+1] = values[j];
values[j] = hold;
}
}
}
return;
}
Note: The rest of my code looks sound to my amateur coding mind, but please give me pointers on what i can improve, what can be better, etc. I thought about using recursion for the bubble sort but i'm not yet as comfortable with C as I'd like to be to implement that. However if you have suggestions i'll be more than happy to read them.
thanks!
Looks like your function is sorting the array (although with some bugs) and you are just printing the result incorrectly. printf doesn't know how to print arrays. Instead, you need to use a loop to print each integer one at a time:
for(int i=0; i<5; i++){
printf("%d ", arr[i]);
}
printf("\n");
After changing this, the output is 1 2 3 4 5, as expected.
However, as mentioned in the comments, there are some bugs in the implementation of the bubblesort. For example, it tries to read elements from indedex after the end of the array, which is undefined behavior (namely, j+1 can be 5, which is out of bounds). I would recommend checking your book again to get a correct implementation of bubblesort.
There is one issue in you bubble sort code which must be fixed. Your inner loop has the issue:
/* for (int j = 0, hold = 0; j < n-i; j++) { */ // ISSUE here
for (int j = 0, hold = 0; j < n-i-1; j++) { // j < n-i-1 should be the condition
This is becasue, take the case of when i = 0, i.e. the first iterartion of outer for loop. This time, j < n - i will be true when j is one less than n - which is the last index of your array. Then you do comaprision between values[j] and values[j+1], where values[j+1] is clearly out of bound of your array. This will invoke undefined behavior, and your function will not give deterministic results.
Next improvement could be that your outer loop only needs to iterate from i = 0 till i < n-1, i.e. one times less than the total elements. You are interating one time more than needed.
Third, you can use a flag to keep track of weather you swap at least once in your inner loop. If there there are no swaps in inner loop then it means that array is already sorted. So at the end of each iteration of inner loop you can see if any swap was done, and if no swaps were done then break out of the outer loop. This will improve performance in cases where array is already almost sorted.
void bubbleSort(int values[], int n)
{
int swap; // To use as a flag
// for (int i = 0; i < n; i++) {
for (int i = 0; i < n-1; i++) {
swap = 0; // set swap flag to zero
// for (int j = 0, hold = 0; j < n-i; j++) {
for (int j = 0, hold = 0; j < n-i-1; j++) {
if (values[j] > values[j+1]) {
hold = values[j+1];
values[j+1] = values[j];
values[j] = hold;
swap = 1; // swap was done
}
}
if (swap == 0) // If no swap was done
break; // Means array already sorted
}
return;
}
And, although not related to your sorting function, as others have pointed out, printf("%i", arr); is wrong, and will invoke undefined behavior because you are using a wrong format specifier in printf. It seems like you are trying to print the array. For that you can do:
// printf("%i", arr);
for (int i = 0; i < 5; i++)
printf("%d ", arr[i];)
printf("\n");
Your code already sorts the array in-place - although there is a bug in it. I'll address the subject of the question only (in-place sorting of an array in C) as comments have already highlighted the bugs with the sort function.
The print-out of the result is incorrect though as it tries to print the arr pointer as an integer:
sort.c:10:18: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat]
printf("%i", arr);
~~ ^~~
1 warning generated.
However changing this to:
for (int i = 0; i < 5; i++)
printf("%i", arr[i]);
fixes the problem with the output.
Perhaps your confusion comes from how arrays are actually a syntactic way to access pointers in C. arr is a pointer. arr[1] is the same as *(arr + 1) (the contents of the pointer arr + 1 using pointer arithmetic, which increments the pointer by the sizeof the type). So when you pass arr into the function, you are passing a pointer to the existing array, then you are modifying its contents, sorting the array in-place.
i'm writing a simple C program where i'm getting the names of the places(lugares) that have been raining, this is just a practice exercise, the thing is that somehow after the cycle where i get the amounts of pluviosity(pluviosidad) the 2d char array of places(lugares) gets corrupted and its first element loses its content and ends up with garbage, I've been thinking of why this happens in the last 4 hours trying to fix this and I don't see why it happens. Any help would be highly appreciated, thanks in advance!
PD: As far as i'm aware of a 2D Char array works like this [sizeofthearray][lengthofeachelement] so I don't know if somehow i'm making this array unstable, since i'm just using the %-10s to format the outputs. And the lengths of its contents aren't even beyond to 12-15 characters i placed 25 just in case i need more when it gets evaluated.
const int nDias = 5;
const int nLugares = 3;
int i, j;
// Arrays Creation
char lugares[nLugares][25];
float pluviosidad[nLugares][nDias];
// A) Data loading
for (i = 0; i<nLugares; i++){
printf("Ingrese el Nombre del Lugar %d:\n", i + 1);
gets_s(lugares[i]);
fflush(stdin);
}
// Somehow after these 2 cycles finish, the "lugares" 2d char array gets corrupted. (I noticed this when doing a debugging session in visual studio)
for (i = 0; i<nLugares; i++){
system("cls");
for (j = 0; j<nDias; j++){
printf("Ingrese pluviosidad para %s en el dia %d: ", lugares[i], j + 1);
scanf_s("%f", &pluviosidad[j][i]);
}
}
// Output Data
printf("\t\tLugares\n");
printf("%-10s", "Dias");
// and here I try to see its contents and in this case of 3 elements on the lugares 2d char array, the first element loses its contents and ends up with garbage.
for (i = 0; i<nLugares; i++)
printf("%-26s", lugares[i]);
I'm programming on Ubuntu 14.04 using the gcc compiler.
I am using the rand(); function to give values to the elements of my array.
( rand() % 101; actually, so I don't get values higher than 100 )
Then I want to sort the elements of my array using the 'Selection sort' algorithm, but when I print(f) them out, the first two elements are 0's, even though there are no 0's on my array (most of the time).
Here's my code, please review it, compile it, try it out and guide me:
#include <stdio.h>
#include <stdlib.h>
int main() {
int i, j, tam_arreglo;
time_t t;
int *a;
int aux;
/* Here I'm asking for you to give me the size of the array and store it in tam_arreglo */
printf("Introduzca el tamaƱo del arreglo: \n");
scanf("%d",&tam_arreglo);
/* Making my array the size I just asked you */
int array[tam_arreglo];
srand((unsigned) time(&t));
/* Dynamic random filling of the array */
printf("El arreglo sin ordenar es: \n");
a = malloc(tam_arreglo * sizeof(int));
for(i = 0 ; i < tam_arreglo ; i++) {
a[i] = rand()%101;
printf("%d\n", a[i]);
}
free(a);
/* My 'Selection sort' algorithm */
for(i = 0; i < tam_arreglo; i++) {
for(j = i+1; j < tam_arreglo; j++) {
if(a[i] > a[j]) {
aux = a[i];
a[i] = a[j];
a[j] = aux;
}
}
}
/* Here's when I get the error, the first two elements printed are 0's */
printf("El arreglo ordenado es: \n");
for(i = 0; i < tam_arreglo; i++) {
printf("%d\n", a[i]);
}
return(0);
}
What am I doing wrong?
You should not free() the array yet, when you will no longer access the memory pointed to buy the pointer, then you call free() but never before.
When you access the a pointer in the code following free(a); there will be garbage because the memory was free()'d already.
So, move free(a) after the second for loop just before return and it should work well.
And also, you don't need to use parentheses with return, and check the value returned by scanf() in case of invalid input, since in that case tam_arreglo will be uninitialized and your program will invoke undefined behavior.