换行符替换char数组中的第一个值

时间:2014-11-18 17:06:29

标签: c arrays

我遇到一个简单数组的问题。突然第一个值(即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;
}

返回here1here2 here3为什么会这样?!!

2 个答案:

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