C 换行符替换字符数组中的第一个值
我在使用简单数组时遇到问题。突然,第一个值(即C 换行符替换字符数组中的第一个值,c,arrays,C,Arrays,我在使用简单数组时遇到问题。突然,第一个值(即名称[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[PLA
名称[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';
}
这也会打印出names
数组中的第一个值,但效果很好
但是由于某种原因,在function2
中,当我打印出数组的第一个值时,如下所示:
printf("%s", names[0]);
它只返回换行符
如果在输入function1
之前输入function2
,它会完美地返回名称[0]
因此,这意味着功能1
必须存在问题。但是这是很多与名称
数组无关的代码
你知道为什么会这样吗
编辑: 这个
if(matchesComplete==匹配)
{
printf(“此处为2-%s”,名称[0]);
轮=轮+1;
/*重置游戏显示计数*/
对于(x=0;x<10;x++)
{
gamesPlayed[x]=10;
}
if(四舍五入)
{
printf(“\n您现在进入第%d轮!\n”,第二轮);
printf(“此处为3-%s”,名称[0]);
}
打破
}
返回
此处1
和此处2
但不此处3
为什么 首先,您不应该使用scanf,它容易受到安全攻击(,请参阅安全)。如果使用格式字符串%s,并且没有宽度说明符,则如果输入的名称太长,可能会有效地覆盖内存中的下一个变量。因此,您应该确保格式说明符应该是%19s之类的东西,名称为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将使
输出函数2。黄金法则:始终在printf文本的末尾添加\n(除非您希望文本在以后才能打印)。//此代码块包含一些错误。
对于(x=0;x
我用新的scanf
方法更新了我的问题,但问题仍然存在!未从标准库中弃用。一些供应商(例如:Micro$oft)通过警告将其弃用为不安全,并在其位置上培养了类似的功能。正确使用的scanf()
是安全的。它不像scanf
是一种新的、可怕的、可憎的东西,如此卑鄙,可以说根本不应该成为标准库的一部分。是的,你对micro$oft问题的看法是正确的。我忘了仔细检查所有MSDN信息:)不过大多数编译器都有增加安全性的技巧。例如G_GNUC_SCANF(),它可以启用变量的类型检查。使用scanf时应始终伴随警告…好的。。。fgets解决了安全问题。“Here3”问题可能是文本结尾缺少“\n”。我已使用新的scanf方法更新了我的问题,但问题仍在继续!根据scanf手册,如果是%s字段:匹配一系列非空白字符;下一个指针必须是指向字符数组的指针,该数组的长度足以容纳输入序列和自动添加的终止空字节('\0')。输入字符串在空白处或最大字段宽度处停止,以先出现的为准。@jcoppens,正如我说的,我不再使用scanf了@马西米兰,是的,我注意到了(尽管我相信评论中仍然提到了scanf)。上面的评论是针对用户3629249的,用户的评论有一些问题。我真的建议您在出现问题的地方发布代码的工作部分。如果我们必须粘贴和粘合,并完成缺少的内容,您可能无法找到受害者来调试它。
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;
}
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.
//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'}};