I was working with a group on a Google Code Jam practice problem (you can read it here). Our code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
main(){
int c;
int n = 0;
int l = 0;
int d = 0;
int caseCount = 0;
int i = 0;
int j = 0;
//A boolean value used in determining parenthesees.
bool letBool = false;
//A boolean value used in determining something;
bool wordBool = false;
//Temporary space for test characters
char test[1000];
//Gets word length
while((c=getchar())!=' ' && c!= '\n'){
l = (l * 10) + c - '0';
//printf("%d\n", l);
}
//Gets number of valid words.
while((c=getchar())!=' ' && c!= '\n'){
d = (d * 10) + c - '0';
//printf("%d\n", d);
}
//Gets number of test cases.
while((c=getchar())!= '\n'){
n = (n * 10) + c - '0';
//printf("%d\n", n);
}
//Array of all valid words.
char dict[d][l];
c=getchar();
//While we still have words to read in.
while(i < d){
//If not new line
if(c!='\n'){
//Then read character
dict[i][j] = c;
}
else{
i++;
j=0;
}
c=getchar();
j++;
}
i = 0;
j = 0;
while(i < n){
j = 0;
while((c=getchar())!='\n' && c!=EOF){
putchar(c);
test[j] = c;
j++;
}
putchar('\n');
test[j+1] = '\0';
printf("%s\n", test);
int word = 0;
//Going through valid words
while(word < d){
wordBool=true;
j = 0;
int letter = 0;
//Going through valid letters
while(letter < l){
letBool=false;
if(test[j] == '('){
while(test[j++]!=')'){
if(dict[word][letter]==test[j]){
letBool=true;
//printf("%s%d%s%d\n" "letBool is true at word: ", word, "letter: ", letter);
}
}
}
else{
if(test[j]==dict[word][letter]){
letBool=true;
//printf("%s%d%s%d\n" "letBool is true at word: ", word, "letter: ", letter);
}
}
j++;
letter++;
if(!letBool){
wordBool=false;
//printf("%s%d%s%d\n" "wordBool is false at word: ", word, "letter: ", letter);
}
}
if(wordBool){
caseCount++;
}
word++;
}
printf("%s%d%s%d\n", "Case #", i+1, ": ", caseCount);
i++;
j=0;
caseCount=0;
}
}
The problem is the output seems to correctly read the input for the "recieved alien code" part with out putchar, but when it is entered into the test case, it becomes corrupted. Here is the part I am talking about:
while((c=getchar())!='\n' && c!=EOF){
putchar(c);
test[j] = c;
j++;
}
putchar('\n');
test[j+1] = '\0';
printf("%s\n", test);
When we give it this input:
3 5 4
abc
bca
dac
dbc
cba
(ab)(bc)(ca)
abc
(abc)(abc)(abc)
(zyx)bc
we get
ab)(bc)(ca)
ab)(bc)(ca)
7
Case #1: 0
abc
abc
b
Case #2: 1
(abc)(abc)(abc)
(abc)(abc)(abc)
Case #3: 0
(zyx)bc
(zyx)bcb
Case #4: 0
(
Case #5: 0
So, we can't understand why there are random characters like 7 and b printed out.
Change this:
test[j+1] = '\0';
to this:
test[j] = '\0';
The reason is that you already incremented j
's value, at the end of the while loop, before the terminating condition was met:
j = 0;
while((c=getchar())!='\n' && c!=EOF){
putchar(c);
test[j] = c;
j++; <------
}
putchar('\n');
test[j] = '\0';
So, with test[j + 1]
, you actually skipped a cell. That means that you are experiencing Undefined Behaviour, since that skipped cell contains junk, since test
was not initialized to nothing. As a result, we do not know what that cell contains, it contains junk.
Output with the corrected code:
gsamaras@gsamaras:~$ gcc -Wall px.c
gsamaras@gsamaras:~$ ./a.out
3 5 4
abc
bca
dac
dbc
cba
(ab)(bc)(ca)
abc
(abc)(abc)(abc)
(zyx)bcab)(bc)(ca)
ab)(bc)(ca)
Case #1: 0
abc
abc
Case #2: 1
(abc)(abc)(abc)
(abc)(abc)(abc)
Case #3: 0
(zyx)bc
(zyx)bc
Case #4: 0
Moreover, use:
int main(void) {
...
return 0;
}
For more, read this: What should main() return in C and C++?