I'm seriously mad right now. I need to compare one string with second, when chars from second string can somehow create first string. Example
foo1 = bill
foo2 = boril
foo2 can create foo1, because it contains all the letters from foo1.
So there's my program:
secret = religion
lettersGuessed = religonvpst
for(i = 0; i < lenSecret; i++){
for(l = 0; l < lenGuessed; l++)
printf("A: %c, B: %c, C: %d\n", secret[i], lettersGuessed[l], count);
if(secret[i] == lettersGuessed[l]){
printf("HI\n");
count++;
break;
}
printf("C: %d\n", count);
}
But variable count always stays at 0. This is output from console:
http://pastebin.com/YrHiNLNi
As you can see right from beginning, when secret[i] == lettersGuessed[l] in if should return true(1), it returns false(0). What's wrong with this? Why it's not working?
It's because you don't have curly braces after your second for loop. If you don't wrap the block of code you want to iterate over with curly braces, only the code before the first semi-colon encountered will be executed. In this case, your second loop will iterate over the printf statement but nothing else. So variable l will always be equal to lenGuessed when the if statement is executed and no letter from the first word matches the last letter of the second word, therefore count is never incremented.
Ok, this is totaly crazy.
Code that I posted in my question was of course wrong, because I forget braces of second for loop. Small, but fatal mistake, I know, but I was seriously mad so I didn't pay attention. Anyway, the original code is following:
int isWordGuessed(char secret[], char lettersGuessed[]){
int i, l, count = 0;
int lenSecret = strlen(secret);
int lenGuessed = strlen(lettersGuessed);
for(i = 0; i < lenSecret; i++)
for(l = 0; l < lenGuessed; l++)
if(secret[i] == lettersGuessed[l]){
count++;
break;
}
return lenSecret == count ? 1 : 0;
}
At first, it was returning 0. After compiling it with different tools and launching it on two different OS (Windows 7 64-bit and Windows XP 32-bit) i was finaly able to get 1 from that function.
It seems like variable count had non-zero value while launching, so instead of int i, l, count; I wrote int i, l, count = 0;
Well, now I don't understand only one thing - why sometimes variables has non-zero value even when I never touched them. It happened to my before, but only in C, in other languages I never had such a problem.
Related
I'm trying to replace the jth value of the function's input string to '0' whenever the ith value of alphabet is contained in the function's input.
I am expecting this for-loop to increment i whenever the alphabet[i] equals input x[j] but it gets stuck at i when it does. What is going on here??
P.S This is an introductory programming course (CS50) and it uses different syntax then standard C.
void checkrepeat(string x)
{
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
}
}
The output of function with value x = 'AAA' gives me
0,A,0AA
0,A,00A
0,A,000
I am expecting it to give me
0,A,0AA
1,B,0AA
2,C,0AA
This is my first post so pardon me if I am too verbose or not following any unsaid rules; I would be happy to include any suggestions as I contribute more.
I could be wrong but looks like "Your expected output pattern" and "your interpretation of assignment" are contradictory.
Let me explain why ?
1 - Expected Output for x='AAA'
I am expecting it to give me
0,A,0AA
1,B,0AA
2,C,0AA
2 - your interpretation of assignment
replace the 'j'th value of the function's input string to '0' whenever the 'i'th value of alphabet is contained in the function's input.
Here you are interpreting whenever as "update input string with '0' for **ALL** matches"
i.e. replace all A's with 0's.
If I follow interpretation [2] then output of your function code "as is" for x='AAA' would print like this
0,A,0AA
0,A,00A
0,A,000
i loop with j=1 will run but nothing is printed because there is no B in input string
i loop with j=2 will run but nothing is printed because there is no C in input string
and this will continue till Z
and the loop will end
BTW - I hope you can see the waste of CPU processing power in your solution.
If your interpretation [2] is correct then your expectation of output [1] is erroneous and vice versa.
ASSUMING interpretation [2] is correct then you need to change your code as below however the output would be different from expected output [1].
void checkrepeat(char x[])
{
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
}
}
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
And output of your modified function for x='AAA' would print like this
0,A,000
1,B,000
2,C,000
...
25,Z,000
As an example when x='ABCDZABCDZ' then the expected output would look like
0,A,0BCDZ0BCDZ
1,B,00CDZ00CDZ
2,C,000DZ000DZ
3,D,0000Z0000Z
4,E,0000Z0000Z
...
25,Z,0000000000
Open this link to see Working code in C
https://onlinegdb.com/rJhda-gMP
3 - your interpretation of assignment
I am expecting this for-loop to increment the 'i' whenever the alphabet[i] equals input x[j]
Here you are interpreting whenever as "as soon as first match is found update input string with '0' and increment 'i'"
ASSUMING interpretation [3] is correct, following code changes are needed to print your expected output [1]
void checkrepeat(char x[])
{
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphalen = strlen(alphabet);
for (int i = 0; i < alphalen; i++)
{
for (int j = 0; j < strlen(x); j++)
{
if (alphabet[i] == x[j])
{
x[j] = '0';
break;
}
}
printf("%i,", i);
printf("%c,", alphabet[i]);
printf("%s\n", x);
}
}
If I follow interpretation [3] then it meets the expected output [1] and for x='AAA' your function would print like this which
0,A,0AA
1,B,0AA
2,C,0AA
...
25,Z,0AA
As an example when x='ABCDZABCDZ' then the expected output would look like
0,A,0BCDZABCDZ
1,B,00CDZABCDZ
2,C,000DZABCDZ
3,D,0000ZABCDZ
4,E,0000ZABCDZ
...
25,Z,00000ABCDZ
Open this link to see Working code in C
https://onlinegdb.com/rJhda-gMP
Hope it helps.
Firstly, printf("%c,", alphabet[i]);is an error. You probably didn't mean to use the , after %c. Remove it.
Second,Its easy to loose the logic in nested loops, especially as a beginner. Write it down on paper and run through it, If you haven't yet learn about debuggers.
Now,you probably do not want i to ++ when there is a match between alphabet[i]and x[j], because i is your loop counter, and should not be messed with like that (You have likely confused a for loop with a while loop or are coming from something like Scratch).
I would suggest declaring a separate variable, say int x for this task.
As already mentioned in the comments, you haven't actually implemented this incrementation to take place(with a simple x++; in the if statement), and have wrongly assumed that somehow the i++ in your for loop has done it for you .
Again, I'll suggest you to hit the books and go back to see the exact workings of a for loop , which is very frequently used in C , so you cannot afford to be fuzzy on its key concepts.
Also, you seem to expect the string x to remain 0AA ... If this is the case , why would the first statement in you if() be x[j] = '0'; ? This will make every jth element of x that matches with alphabets a '0'.
Further, in the expected output, you have expected alphabet[i] to be A , then B , then C, despite clearly stating in your question that you had passed x as "AAA" (which obviously cannot then match with B or C).
Maybe you haven't written the 'I expect' with clear forethough. Please do not include sample expected output if it is not possible with the code you have supplied in the question. It confused me, and could confuse anyone. I assume you drastically shortened the code for S.O. but supplied the expected output of the original code you have somewehere on your computer.
Just writing some code to sort an array using bubble sort, but right at the start I couldn't even define an array and print it.
Code:
#include <stdio.h>
int main () {
int test[] = {9,9,9,9,9}; //define array
test[2] = 3;
bool checker = false; //is it sorted?
int i = 0;
for(int i = 0; i<=4; i++) //set random numbers for array
{
int g;
g = 4+i;
test[i] = g;
i++;
}
for (int i = 0; i <= 4; ++i ) //print array as normal
{
printf(", ", test[i]);
}
When executed it always outputs:
, , , ,
so the array is empty? or im printing it wrong? or something?
You are printing it wrong.
The line in which you are printing should read printf("%d, ", test[i]);
Also not that you have tagged the question as C++, but are using C related terms. Your #include <stdio.h> should be replaced by #include <iostream> and you should be using cout instead of printf for outputting data.
You have two problems in your code.
First, the initial 'for' loop uses 'i' as its counter variable, and your increment condition is 'i++'. That means 'i' automatically increments through each loop iteration; yet within the loop, you specify 'i++', meaning you will see the value of 'i' bumped twice with each pass. Eliminate the extraneous increment.
Second, you are printing the array incorrectly. You need to add a format qualifier such as '%d' to tell printf to use the first argument as a replacement for that specifier.
Lastly, you've indicated C++ for this code, but it really isn't. It's classic C.
I want to initialize an 16-cel-long array with 0, 1, 2 and 3 by blocks of four cels. So here is my first attempt at this:
int main(void) {
int t[16];
int i;
for (i = 0; i<=15; t[i++]=i/4)
{
printf("%d \n", t[i]);
}
return 0;
}
However, here is what I get. I know I can do it differently by just getting the affectation into the for loop, but why does this not work?
EDIT: Please do note that the printf only serves to check what the loop did put in the array.
The initialization works fine; you're just printing the cell before initializing it. Remember that the loop increment is done after each iteration. If you unroll the loop, you have:
i = 0; /* i is now 0 */
print(t[i]); /* prints t[0] */
t[i++] = i/4; /* sets t[0] */
/* i is now 1 */
print(t[i]); /* prints t[1] */
t[i++] = i/4; /* sets t[1] */
/* i is now 2 */
print(t[i]); /* prints t[1] */
/* etc. */
As well as the off-by-one errors with the loop begin/end that have been mentioned in other posts, this code:
t[i++]=i/4
causes undefined behaviour because i is read and written without a sequence point. "Undefined behaviour" means anything can happen: the value could be 3, or 4, or anything else, or the program could crash, etc.
See this thread for more in-depth discussion, and welcome to C..:)
I do not understand what you are trying to accomplish, but please let me show you a similar piece of code, first.
int main(void) {
int t[16];
int i;
//edited the code; providing standard way to do the task
for (i = 0; i<=15; i++)
{
t[i]=i/4;
printf("%d \n", t[i]);
}
return 0;
}
EDIT:
The while loop should be written that way:
int i = 0;
while (i<=15){
t[i] = i%4;
i++;
}
Which means set t[i] equal to i%4 and then increment i.
Since you are a beginner, I've updated the for loop and it now provides a standard way to do your task. It's better to have a simple increment on the third for loop command; do the rest of the job inside the for loop, as described above.
#naltipar: Yeah, I just forgot to initialize the first cel, just like grawity pointed out. Actually, the version I wrote for myself was with i++ but even then, since the third expression is executed after each loop, it sent out the same result. But whatever, it is fixed now.
However, I've got another problem which I'm sure I'm missing on but still can't figure it out:
int i = 0;
while (i<=15)
t[++i] = i%4;
This was first:
for(i = 0; i<=15; t[++i] = i%4);
but it resulted with an infinite loop. So in order to make sure that's not a problem specific to for, I switched to while andthe same thing still happens. That being said, it doesn't occur if i replace ++i by i++. I unrolled the whole loop and everything seems just fine...
I'm a beginner, by the way, in case you were wondering.
A clearer way to write this would be much less error-prone:
for (i = 0; i < 16; ++i)
printf ("%d\n", (t[i] = i % 4));
Personally I'd code something that way, but I'd never recommend it. Moreover, I don't really see much benefit in condensing statements like that, especially in the most important category: execution time. It is perhaps more difficult to optimize, so performance could actually degrade when compared to simply using:
for (i = 0; i < 16; ++i)
{
t[i] = i % 4;
printf ("%d\n", t[i]);
}
Even if it is you reading your own code, you make it difficult for your future self to understand. KISS (Keep It Simple, Stupid), and you'll find code is easier to write now and just as easy to modify later if you need to.
Consider this code:
int main()
{
int i;
int ints[3];
ints[0] = 0;
ints[1] = 1;
ints[2] = 2;
for(i = 0; (ints[i])<4 && i<3; i++)
{
printf("%d\n", ints[i]);
}
}
Is there a reason I shouldn't do this sort of conditioning in the loop? I mean, when i becomes 3, will it look for a non-existing value at ints[3]? And if yes, is it ok?, since the loop is going to terminate anyway? It compiles and runs fine, but I was just wondering if there is some sort of a hidden problem with this. Thanks.
In the last iteration of this loop, the expression ints[i]<4 will access ints[3]. Since this access reads past the end of the array ints, the behavior is undefined in C. So yes, this is not good code. It may work most of the time, but the behavior is ultimately undefined.
It will be better to do i < 3 && ints[i] < 4 because the second part of the statement is evaluated only if the first one is true. The way you have it, it will look for ints[3] that does not exist.
It isn't okay to do this, because ints[3] will indeed be accessed. Now, because this is C, you're not going to get an error (unfortunately), but you'll never know for sure what the outcome would be.
Swapping the statements will solve the problem, because the && operator is optimized so that it doesn't evaluate the second condition if the first one is false.
The 'for' keyword expands out the following way:
int i;
for(i = 0; i < 2; i++)
dothing();
becomes
int i;
i = 0; /* first part of (i = 0; ...) */
beginloop:
if (i >= 2) goto endloop; /* second part of (...; i < 2; ...) */
dothing();
i++; /* final part of (...; ...; i++) */
goto beginloop;
endloop:
So, your code would expand out as follows:
i = 0;
beginloop:
if (ints[i] >= 4)
goto endloop;
if (i >= 3)
goto endloop;
printf(...);
i++;
goto beginloop;
endloop:
While this is fine, there is a problem with the ordering of your tests:
(ints[i] < 4) && (i < 3)
You should always check array indexes first to ensure they are valid before using them:
i = 0:
ints[0] < 4 && 0 < 3
i = 1:
ints[1] < 4 && 1 < 3
i = 2:
ints[2] < 4 && 2 < 3
i = 3:
ints[3] < 4 && 3 < 3 /* illegal access to ints[3] */
As a general rule of thumb, always try to order your conditionals in order of cost unless there is a better reason for the ordering, such as priority: In this case, i < 3 is the cheaper of the two tests, plus it is a constraint on the elements of ints you can access, so you checking the index should have a higher priority - you should check it before using it to tests ints[i] for anything.
The way you have written the loop, your code will try to read the non-existing array element ints [3]. That's undefined behaviour; a consequence is that anything can happen. Right now the whole internet is in uproar because of some code in OpenSSL that invoked undefined behaviour.
The loop terminates, that's okay. But you're accessing an area outside of what you're allowed to. It is undefined behaviour. You may get a segmentation anytime. But you're lucky.
Try putting i<3 before. That would work just fine.
for(i = 0; i<3 && (ints[i])<4; i++)
If i becomes 3, the second part is not evaluated. See short circuit evaluation.
I wrote this incredibly stupid code
#include <stdio.h>
main(){
int new[10], i;
for(i=1; i<=10; ++i){
new[i] = 0;
}
for(i=1;i<=10; ++i)
{
printf("%d", new[i]);
}
}
I compiled this using GCC on Xubuntu and then did the ./a.out. The cursor is just blinking resulting in no output. The same is the case when tried to debug with gdb. It runs and then stays with the blinking cursor.
Any help?
C arrays are 0 indexed - your program writes outside the boundaries of the new array, so it causes undefined behaviour. In this case, you probably are overwriting the i variable, so you end up with an infinite loop. You need to change your loops:
for (i = 0; i < 10; i++)
{
new[i] = 0;
}
and:
for (i = 0; i < 10; i++)
{
printf("%d", i);
}
you need to have a new line character to see the output , or flush the stdout otherwise sometimes it doesn't print, or it will be combined with the next line... try:
printf("%d\n", new[i]);
also, set your for loop from 0 to 9
int new[10] - Here new array can store 10 elements of type integer. You can access these elements from 0th to 9th index of array. Accessing beyond 9th index is undefined behavior.