我遇到一个简单数组的问题。突然第一个值(即names[0]
)被换行符替换
functionOne(names[PLAYERS][NAME_LEN]);
function2(names[PLAYERS][NAME_LEN]);
function2(names[PLAYERS][NAME_LEN]);
int main(void) {
char names[PLAYERS][NAME_LEN];
functionOne(names);
}
functionOne(names[PLAYERS][NAME_LEN])
{
function1(names);
function2(names);
}
名称全部使用scanf
初始化,如:
for (x=0; x < PLAYERS; x++){
printf("Please enter the name of player %d: ", x + 1);
fgets(names[x], NAME_LEN, stdin);
//remove line break from the end of the fgets
size_t length = strlen(names[x]);
names[x][--length] = '\0';
}
内部function1
我所做的只涉及names
是从一个数组复制到另一个数组:
if (score2 == 3)
{
//player 2 won. So move to round 2
strcpy(roundTwoNames[game - 1], names[player2]);
}
else
{
//player 1 won. So move to round 2
strcpy(roundTwoNames[game - 1], names[player1]);
}
printf("Here - %s", names[0]);
roundOneScores[player1] = score1;
roundOneScores[player2] = score2;
这也打印出names
数组中的第一个值但效果很好。
但由于某些原因function2
当我打印出数组的第一个值时,如:
printf("%s", names[0]);
它只返回一个换行符?
如果我在输入function2
之前输入function1
它会完美地返回名称[0]。
function1
必须有问题。但这是很多与names
数组无关的代码。
你知道为什么会这样吗?
此
if (matchesComplete == matches)
{
printf("Here2 - %s", names[0]);
round = round + 1;
/* reset gamesPlayed count */
for (x=0; x < 10; x++)
{
gamesPlayed[x] = 10;
}
if(round < 5)
{
printf("\nYou are now into round %d!\n", round);
printf("Here3 - %s", names[0]);
}
break;
}
返回here1
和here2
但不 here3
为什么会这样?!!
答案 0 :(得分:0)
首先,您不应该使用scanf,它容易受到安全攻击(http://en.wikipedia.org/wiki/Scanf_format_string,请参阅安全性)。使用格式字符串%s,没有宽度说明符,如果输入的名称太长,则可以有效地覆盖内存中的下一个变量。所以你应该确保格式说明符应该是%19s,在NAME_LEN中是20。
请注意,scanf无法知道您在内存中保留的字段的宽度。你必须保护缓冲区!
scanf现在被认为是如此危险,以至于它在最近的编译器中已被弃用。有些编译器发出警告,有些只是将函数分类为不存在。
注意:@WhozCraig通知我scanf不被弃用。他是对的 - 似乎只有微软这样做了。
修改:这里有一个提示:
printf("Test"); // will print only a line break, which isn't even from the
// from the print This is because the runtime routines will
// 'cache' the printed text till the next \n is to be
// be printed.
// So, if you want to print debug info, always do this:
printf("Text\n"); // This will force the print.
所以,我认为这解释了你的问题。如果在function1之前调用function2,则在调用function1之前输出不起作用。 \ n那里会有 function2的输出出来了。黄金法则:总是在你的printf文本末尾添加\ n(除非你希望文本不要打印到以后)。
答案 1 :(得分:-1)
//this code block contains a few errors.
for (x=0; x < PLAYERS; x++)
{
printf("Please enter the name of player %d: ", x + 1);
scanf("%s", names[x]);
}
//The errors are:
//1) scanf does not append a termination char to the string.
//2) the returned value from scanf() is not being checked
// to assure the name was actually input successfully
//3) the format parameter of scanf() is not allowing for white space, like newlines
//suggest:
for (x=0; x < PLAYERS; x++)
{
printf("Please enter the name of player %d: ", x + 1);
if( 1 != scanf(" %s", names[x]) ) // notice the leading ' ' in the format parameter
{
// handle error
}
}
//This code block contains an error:
functionOne(names[PLAYERS][NAME_LEN]);
function2(names[PLAYERS][NAME_LEN]);
function2(names[PLAYERS][NAME_LEN]);
//the errors are:
//there is two prototypes for function2() and no prototype for function1()
//the compiler will assume all parameters and return types for function1() are int.
//the return type for each function is not defined (the default is int)
//suggest:
void functionOne( player_t names[] );
void function1( player_t names[] );
void function2( player_t names[] );
//the current method of defining the function parameter:
names[PLAYERS][NAME_LEN] is very awkward.
//suggest:
typedef char player[NAME_LEN] player_t
//then creating an array of the player_t and init to all '\0'
player_t names[PLAYERS] = {{'\0'}};