Outputs differing -- can't understand the logic - c

Basically I am creating an array 'string' with some values in it, creating another array ('auxstring'), and then storing all the values of the initial array in reverse order. Finally I print them out.
How come when I execute the program as is, I get garbage as the output? However, if I put another number in the 'string' array (ie: {3,1,1,3,4}) it works fine (outputs: 43113).
It also works fine if I add this line:
"printf("%d\n", sizeof(auxstring));"
right before the for loop.
I'm sure it's something very basic, but I would like to understand what is going on behind the scene and why adding a number at the end of the initial string, or putting that printf, somehow outputs the accurate numbers.
Thanks.
#include <stdio.h>
#include <string.h>
int main(void) {
int i=0, j, l;
char string[] = {3,1,1,3};
char auxstring[sizeof(string)];
for (j=(sizeof(auxstring) - 1); j >= auxstring[0]; j--) {
auxstring[j] = string[i];
i++;
}
for (l=0; l < sizeof(auxstring); l++) {
printf("%d",auxstring[l]);
}
return 0;
}

The condition in the for loop
for (j=(sizeof(auxstring) - 1); j >= auxstring[0]; j--) {
^^^^^^^^^^^^^^^^^^
does not make sense because at least the array auxstring is not initialized.
Also the loop is complicated because it uses two variables as indices.
Ans the variables i, j, l should have the type size_t - the type of the returned value of the operator sizeof.
The program can look the following way
#include <stdio.h>
int main(void)
{
char string[] = { 1, 2, 3, 4 };
char auxstring[sizeof( string )];
const size_t N = sizeof( string );
for ( size_t i = 0; i < N; i++ )
{
auxstring[i] = string[N - i - 1];
}
for ( size_t i = 0; i < N; i++ )
{
printf( "%d", auxstring[i] );
}
return 0;
}
Its output is
4321

The loop condition should be j >= 0.
Right now you compare against the uninitialized value in auxstring[0], which is indeterminate (and will seem random).

Related

Inconsistent output given by same code on different C compilers

Different compilers are giving different outputs for the same logic in my algorithm.
I wrote the following code for a C code exercise.
The code checks for the longest string in a string vector.
But the same logic gives two different outputs.
Here's what is happening. I have no idea what I did wrong.
First version - without a printf() inside the if condition
Here the if (j > longest) just attributes new values for int longest and int index.
#include <stdio.h>
int main(void) {
char *vs[] = {"jfd", "kj", "usjkfhcs", "nbxh", "yt", "muoi", "x", "rexhd"};
int longest, index = 0;
/* i is the index for elements in *vs[].
* "jfd" is 0, "kj" is 1... */
for (int i = 0; i < sizeof(*vs); i++) {
/* j if the index for string lengths in vs[].
* for "jfd", 'j' is 0, 'f' is 1... */
for (int j = 0; vs[i][j] != '\0'; j++) {
/* if j is longer than the previous longest value */
if (j > longest) {
longest = j;
index = i;
}
}
}
printf("Longest string = %s\n", vs[index]);
return 0;
}
I ran it on https://replit.com/. It gave the unexpected output for longest string of "jfd". https://replit.com/#Pedro-Augusto33/Whatafuck-without-printf?v=1
Second version - with a printf() inside the if condition
Now I just inserted a printf() inside the if (jf > longest) condition, as seen in the code block bellow.
It changed the output of my algorithm. I have no idea how or why.
#include <stdio.h>
int main(void) {
char *vs[] = {"jfd", "kj", "usjkfhcs", "nbxh", "yt", "muoi", "x", "rexhd"};
int longest, index = 0;
/* i is the index for elements in *vs[].
* "jfd" is 0, "kj" is 1... */
for (int i = 0; i < sizeof(*vs); i++) {
/* j if the index for string lengths in vs[].
* for "jfd", 'j' is 0, 'f' is 1... */
for (int j = 0; vs[i][j] != '\0'; j++) {
/* if j is longer than the previous longest value */
if (j > longest) {
printf("Whatafuck\n");
longest = j;
index = i;
}
}
}
printf("Longest string = %s\n", vs[index]);
return 0;
}
I also ran it on https://replit.com/. It gave the expected output for longest string of "usjkfhcs". https://replit.com/#Pedro-Augusto33/Whatafuck-with-printf?v=1
Trying new compilers
After replit.com giving two different outputs, I tried another compiler to check if it also behaved strangely. https://www.onlinegdb.com/online_c_compiler gives random outputs. Sometimes it's "jfd", sometimes it's "usjkfhcs". https://onlinegdb.com/iXoCDDena
Then I went to https://www.programiz.com/c-programming/online-compiler/ . It always gives the expected output of "usjkfhcs".
So, my question is: why are different compilers behaving so strangely with my algorithm? Where is the flaw of my algorithm that makes the compilers interpret it different?
The code does not make sense.
For starters the variable longest was not initialized
int longest, index = 0;
So using it for example in this statement
if (j > longest) {
invokes undefined behavior.
In this for loop
for (int i = 0; i < sizeof(*vs); i++) {
the expression sizeof( *vs ) is equivalent to expression sizeof( char * ) and yields either 4 or 8 depending on the used system. It just occurred such a way that the array was initialized with 8 initializers. But in any case the expression sizeof( *vs ) does not provide the number of elements in an array and its value does not depend on the actual number of elements.
Using the if statement within the for loop in each iteration of the loop
for (int j = 0; vs[i][j] != '\0'; j++) {
/* if j is longer than the previous longest value */
if (j > longest) {
longest = j;
index = i;
}
}
Also does not make sense. It does not calculate the exact length of a string that is equal to j after the last iteration of the loop. So in general such a loop shall not be used for calculating length of a string.
Consider a string for example like "A". Using this for loop you will get that its length is equal to 0 while its length is equal to 1..
It seems you are trying to find the longest string a pointer to which stored in the array.
You could just use standard C string function strlen declared in header <string.h>. If to use your approach with for loops then the code can look the following way
#include <stdio.h>
int main(void)
{
const char *vs[] = { "jfd", "kj", "usjkfhcs", "nbxh", "yt", "muoi", "x", "rexhd" };
const size_t N = sizeof( vs ) / sizeof( *vs );
size_t longest = 0, index = 0;
for ( size_t i = 0; i < N; i++ )
{
size_t j = 0;
while ( vs[i][j] != '\0' ) ++j;
if ( longest < j )
{
longest = j;
index = i;
}
}
printf( "Longest string = %s\n", vs[index] );
printf( "Its length = %zu\n", longest );
return 0;
}

Is this syntax array inside array?

Below code snippet from Leetcode. the given exercise is to find the longest substring without repeating characters. I am trying to understand the logic from someone has posted the solution
I have below question is
I have cnt and s are array. is this array inside array cnt[s[j]] and cnt[s[j]]++? how it works, please help to explain. I have tried to visualize the code execution using this
I have tried to understand below line . I tried to visualize the code execution using
#include <stdio.h>
int lengthOfLongestSubstring(char * s)
{
if (s[0] == '\0')
return 0;
if (s[1] == '\0')
return 1;
int i, j, len, max = 0;
int cnt[255] = {0}; // array of counter
//memset(cnt,0,sizeof(cnt));
for (i=0; s[i]!=0; i++)
{
len = 0;
for (j=i; s[j]!=0; j++)
{
if (cnt[s[j]] == 0) /* What does this mean since cnt and s both are array? is this called array inside array ? */
{
printf("iteration %d %c\n",j,s[j]);
cnt[s[j]]++;
len++;
}
else
{ /* if character are not equal */
break;
}
}
if (len > max)
max = len;
}
return max;
}
int main()
{
char string1[] = "abcabcbb";
printf("%d",lengthOfLongestSubstring(string1));
return 0;
}
The syntax a[b[i]] means the value in b[i] references the index from a to read.
So if you have int a[] = { 10, 100, 1000, 10000, 100000}; int b[] = { 3, 2, 1, 0}; then a[b[0]] resolves to a[3] which has the value 10000.
Note that this requires b to only have values that are valid indexes into a.
It's not an array inside an array, it's using one array to get the subscript into another array.
When you see a complex expression you don't understand, split it up into simpler expressions.
cnt[s[j]]++;
is roughly equivalent to
int charcode = s[j];
cnt[charcode]++;
s is a string, so s[j] contains a character code. So this increments the element of cnt corresponding to that character code, and the final result is frequency counts of each character.

Error: assignment to expression with array type while using selection-sort

Basically, I'm trying to sort an agenda with 3 names using selection sort method. Pretty sure the selection sort part is OK. The problem is that apparently my code can identify the [0] chars of the string, but cannot pass one string to another variable. Here is my code:
include <stdio.h>
typedef struct{
char name[25];
} NAME;
int main(){
int a, b;
char x, y[25];
static NAME names[]={
{"Zumbazukiba"},
{"Ademiro"},
{"Haroldo Costa"}
};
for(a=0; a<4; a++){
x = names[a].name[0];
y = names[a];
for(b=(a-1); b>=0 && x<(names[b].name[0]); b--){
names[b+1] = names[b];
}
names[b+1].name = y;
}
}
I keep getting this error message:
main.c:21:11: error: assignment to expression with array type
y = names[a];
There are at least two errors in your code, in the line flagged by your compiler. First, you can't copy character strings (or, indeed, any other array type) using the simple assignment (=) operator in C - you need to use the strcpy function (which requires a #include <string.h> line in your code).
Second, you have declared y as a character array (char y[25]) but names is an array of NAME structures; presumably, you want to copy the name field of the given structure into y.
So, instead of:
y = names[a];
you should use:
strcpy(y, names[a].name);
Feel free to ask for further clarification and/or explanation.
For starters I do not see the selection sort. It seems you mean the insertion sort.
Arrays do not have the assignment operator. So statements like this
names[b+1].name = y;
where you are trying to assign an array are invalid.
And in statements like this
y = names[a];
you are trying to assign an object of the structure type to a character array.
Moreover the loops are also incorrect.
The array has only 3 elements. So it it is unclear what the magic number 4 is doing in this loop
for(a=0; a<4; a++){
and this loop
for(b=(a-1); b>=0 && x<(names[b].name[0]); b--){
skips the first iteration when a is equal to 0.
Here is a demonstrative program that shows how the selection sort can be applyed to elements of your array.
#include <stdio.h>
#include <string.h>
#define LENGTH 25
typedef struct
{
char name[LENGTH];
} NAME;
int main(void)
{
NAME names[] =
{
{ "Zumbazukiba" },
{ "Ademiro" },
{ "Haroldo Costa" }
};
const size_t N = sizeof( names ) / sizeof( *names );
for ( size_t i = 0; i < N; i++ )
{
puts( names[i].name );
}
putchar( '\n' );
for ( size_t i = 0; i < N; i++ )
{
size_t min = i;
for ( size_t j = i + 1; j < N; j++ )
{
if ( strcmp( names[j].name, names[min].name ) < 0 )
{
min = j;
}
}
if ( i != min )
{
NAME tmp = names[i];
names[i] = names[min];
names[min] = tmp;
}
}
for ( size_t i = 0; i < N; i++ )
{
puts( names[i].name );
}
putchar( '\n' );
return 0;
}
The program output is
Zumbazukiba
Ademiro
Haroldo Costa
Ademiro
Haroldo Costa
Zumbazukiba

How to "delete" every element in array by value in C

I have been trying to solve this problem for about 5 days..can't find any solution please send help. I am supposed to implement a function to "delete" every element in an array by value. Let's say my array is "Hello" and I want to delete every "l". So far I can only delete l once. By the way keep in mind I am not allowed to use pointers for this function...(we haven't learned that yet in my school) Here's my code:
#include <stdio.h>
#include <string.h>
void strdel(char array[], char c);
int main(void)
{
char source[40];
printf("\nStrdel test: ");
strcpy(source, "Hello");
printf("\nsource = %s", source);
strdel(source, 'l');
printf("\nStrdel: new source = %s", source);
return 0;
}
void strdel(char array[], char c)
{
int string_lenght;
int i;
for (string_lenght = 0; array[string_lenght] != '\0'; string_lenght++) {}
for (i = 0; i < string_lenght; i++) {
if (array[i] == c) {
for (i = i; array[i] != '\0'; ++i)
array[i] = array[i + 1];
}
}
}
Simple use 2 indexes, one for reading and one for writing. #Carl Norum
void strdel(char array[], char c) {
int read_index = 0;
int write_index = 0;
while (array[read_index] != '\0') {
if (array[read_index] != c) {
array[write_index] = array[read_index];
write_index++; // Only advance write_index when a character is copied
}
read_index++; // Always advance read_index
}
array[write_index] = '\0';
}
The has O(n) performance, much faster than using nested for() loops which is O(n*n).
Details:
OP: By the way keep in mind I am not allowed to use pointers for this function.
Note that array in void strdel(char array[], char c) is a pointer, even though it might look like an array.
int for array indexing is OK for learner and much code, yet better to use size_t. int may lack the range needed. Type size_t is an unsigned type that is neither too narrow nor too wide for array indexing needs. This becomes important for very long strings.
Your problem is related to using the variable i in both loops. So once the inner loop is executed, outer loop will terminate right after.
Use another variable for the inner loop.
void strdel(char array[], char c)
{
int string_lenght;
int i, j;
for (string_lenght = 0; array[string_lenght] != '\0'; string_lenght++) {}
for (i = 0; i < string_lenght; i++) {
if (array[i] == c) {
for (j = i; array[j] != '\0'; ++j) // Use variable j instead of i
array[j] = array[j + 1];
--i; // Decrement i to "stay" at the same index
--string_lenght; // As one character were just removed
}
}
}
The above shows how to make OPs approach work. For a better solution see the answer from #chux : https://stackoverflow.com/a/53487767/4386427

Understanding returning values functions C

I'm trying to understand how the return value of a function works, through the following program that has been given to me,
It goes like this :
Write a function that given an array of character v and its dim, return the capital letter that more often is followed by its next letter in the alphabetical order.
And the example goes like : if I have the string "B T M N M P S T M N" the function will return M (because two times is followed by N).
I thought the following thing to create the function:
I'm gonna consider the character inserted into the array like integer thank to the ASCII code so I'm gonna create an int function that returns an integer but I'm going to print like a char; that what I was hoping to do,
And I think I did, because with the string BTMNMPSTMN the function prints M, but for example with the string 'ABDPE' the function returns P; that's not what I wanted, because should return 'A'.
I think I'm misunderstanding something in my code or into the returning value of the functions.
Any help would be appreciated,
The code goes like this:
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int trovato;
for(int j=0;j<DIM-1;j++) {
if (a[j]- a[j+1]==-1) {
trovato=a[j];
}
}
return trovato;
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("%c",maxvolte(v,dim));
return 0;
}
P.S
I was unable to insert the value of the array using in a for scanf("%c,&v[i]) or getchar() because the program stops almost immediately due to the intepretation of '\n' a character, so I tried with strings, the result was achieved but I'd like to understand or at least have an example on how to store an array of character properly.
Any help or tip would be appreciated.
There are a few things, I think you did not get it right.
First you need to consider that there are multiple pairs of characters satisfying a[j] - a[j+1] == -1
.
Second you assume any input will generate a valid answer. That could be no such pair at all, for example, ACE as input.
Here is my fix based on your code and it does not address the second issue but you can take it as a starting point.
#include <stdio.h>
#include <assert.h>
int maxvolte(char a[],int DIM) {
int count[26] = {0};
for(int j=0;j<DIM-1;j++) {
if (a[j] - a[j+1]==-1) {
int index = a[j] - 'A'; // assume all input are valid, namely only A..Z letters are allowed
++count[index];
}
}
int max = -1;
int index = -1;
for (int i = 0; i < 26; ++i) {
if (count[i] > max) {
max = count[i];
index = i;
}
}
assert (max != -1);
return index + 'A';
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("answer is %c\n",maxvolte(v,dim));
return 0;
}
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int hold;
int freq;
int max =0 ;
int result;
int i,j;
for(int j=0; j<DIM; j++) {
hold = a[j];
freq = 0;
if(a[j]-a[j+1] == -1) {
freq++;
}
for(i=j+1; i<DIM-1; i++) { //search another couple
if(hold==a[i]) {
if(a[i]-a[i+1] == -1) {
freq++;
}
}
}
if(freq>max) {
result = hold;
max=freq;
}
}
return result;
}
int main()
{
char v[] = "ABDPE";
int dim = sizeof(v) / sizeof(v[0]);
printf("\nresult : %c", maxvolte(v,dim));
return 0;
}

Resources