Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 换行符替换字符数组中的第一个值_C_Arrays - Fatal编程技术网

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'}};