C 字符数组的意外输入
C Unexpected inputs with character arrays
我和一个小组一起研究 Google Code Jam 练习题(你可以阅读它 here)。我们的代码如下:
#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] = '[=10=]';
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;
}
}
问题是输出似乎正确读取了带有 out putchar 的 "recieved alien code" 部分的输入,但是当它被输入到测试用例中时,它变得损坏了。这是我正在谈论的部分:
while((c=getchar())!='\n' && c!=EOF){
putchar(c);
test[j] = c;
j++;
}
putchar('\n');
test[j+1] = '[=11=]';
printf("%s\n", test);
当我们给它这个输入时:
3 5 4
abc
bca
dac
dbc
cba
(ab)(bc)(ca)
abc
(abc)(abc)(abc)
(zyx)bc
我们得到
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
所以,我们无法理解为什么会打印出随机字符,如 7 和 b。
改变这个:
test[j+1] = '[=10=]';
对此:
test[j] = '[=11=]';
原因是您已经在 while 循环结束时,在满足终止条件之前递增了 j
的值:
j = 0;
while((c=getchar())!='\n' && c!=EOF){
putchar(c);
test[j] = c;
j++; <------
}
putchar('\n');
test[j] = '[=12=]';
因此,对于 test[j + 1]
,您实际上跳过了一个单元格。这意味着您正在经历 未定义的行为 ,因为跳过的单元格包含垃圾,因为 test
没有初始化为空。结果,我们不知道那个单元格包含什么,它包含 junk.
使用更正后的代码输出:
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
此外,使用:
int main(void) {
...
return 0;
}
有关更多信息,请阅读:What should main() return in C and C++?
我和一个小组一起研究 Google Code Jam 练习题(你可以阅读它 here)。我们的代码如下:
#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] = '[=10=]';
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;
}
}
问题是输出似乎正确读取了带有 out putchar 的 "recieved alien code" 部分的输入,但是当它被输入到测试用例中时,它变得损坏了。这是我正在谈论的部分:
while((c=getchar())!='\n' && c!=EOF){
putchar(c);
test[j] = c;
j++;
}
putchar('\n');
test[j+1] = '[=11=]';
printf("%s\n", test);
当我们给它这个输入时:
3 5 4
abc
bca
dac
dbc
cba
(ab)(bc)(ca)
abc
(abc)(abc)(abc)
(zyx)bc
我们得到
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
所以,我们无法理解为什么会打印出随机字符,如 7 和 b。
改变这个:
test[j+1] = '[=10=]';
对此:
test[j] = '[=11=]';
原因是您已经在 while 循环结束时,在满足终止条件之前递增了 j
的值:
j = 0;
while((c=getchar())!='\n' && c!=EOF){
putchar(c);
test[j] = c;
j++; <------
}
putchar('\n');
test[j] = '[=12=]';
因此,对于 test[j + 1]
,您实际上跳过了一个单元格。这意味着您正在经历 未定义的行为 ,因为跳过的单元格包含垃圾,因为 test
没有初始化为空。结果,我们不知道那个单元格包含什么,它包含 junk.
使用更正后的代码输出:
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
此外,使用:
int main(void) {
...
return 0;
}
有关更多信息,请阅读:What should main() return in C and C++?