当这两个字符都是字符时,为什么我不能使用 strcat 将它们组合起来?

Why can I not combine these two chars using strcat when they are both chars?

我正在为 3ds 开发一款游戏,我希望它是一款 cmd 类型的游戏(我就是喜欢它)。我试图让这个 char 移动到我拥有的任何 x 和 y int 数字,但我收到一个错误。这是我的代码。

/*
    Hello World example made by Aurelio Mannara for libctru
    This code was modified for the last time on: 12/12/2014 21:00 UTC+1
*/

#include <3ds.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
    gfxInitDefault();

    char player[1024] = "\x1b[";
    int tesx = 1;
    char tesxx = tesx + '0';
    char ot[] = ";";
    char oty[] = "H0";
    int test = 3;
    char testt = test + '0';
    //Initialize console on top screen. Using NULL as the second argument tells the console library to use the internal console structure as current one
    consoleInit(GFX_TOP, NULL);
    strcat(player, tesxx);
    strcat(player, ot);
    strcat(player, testt);
    strcat(player, oty);
    //Move the cursor to row 15 and column 19 and then prints "Hello World!"
    //To move the cursor you have to print "\x1b[r;cH", where r and c are respectively
    //the row and column where you want your cursor to move
    //The top screen has 30 rows and 50 columns
    //The bottom screen has 30 rows and 40 columns
    printf(player);

    // Main loop
    while (aptMainLoop())
    {
        //Scan all the inputs. This should be done once for each frame
        hidScanInput();

        //hidKeysDown returns information about which buttons have been just pressed (and they weren't in the previous frame)
        u32 kDown = hidKeysDown();

        if (kDown & KEY_START) break; // break in order to return to hbmenu

        // Flush and swap framebuffers
        gfxFlushBuffers();
        gfxSwapBuffers();

        //Wait for VBlank
        gspWaitForVBlank();
    }

    gfxExit();
    return 0;
}

这是我的错误。我是 C 的新手,所以如果这是一个简单的错误,我很抱歉。我尝试搜索,但在网上找不到任何内容。

C:/Users/Jeremy/Desktop/gaame/source/main.c:24:9: warning: 'strcat' offset 0 is out of the bounds [0, 0] [-Warray-bounds]
   24 |         strcat(player, testt);
      |         ^~~~~~~~~~~~~~~~~~~~~
C:/Users/Jeremy/Desktop/gaame/source/main.c:22:9: warning: '__builtin_stpcpy' offset 0 is out of the bounds [0, 0] [-Warray-bounds]
   22 |         strcat(player, tesxx);
      |         ^~~~~~~~~~~~~~~~~~~~~

考虑 strcat 的签名。

char *strcat( char *dest, const char *src );

它不需要一个 char * 和一个 char,而是两个 char *,并且需要两个 null-terminated 字符串。

函数 strcat 要求它的两个参数都是指向有效字符串的指针,根据定义,该字符串是由空字符终止的字符序列。

然而,在行

strcat(player, tesxx);

第二个函数参数 tesxx 不是指向有效字符串的指针。它是一个简单的 char.

因此,我建议您将此行更改为以下内容:

player[2] = tesxx;
player[3] = '[=11=]';

如果不能保证此行之前的字符串的长度是 2,那么您可以这样写:

size_t len = strlen( player );
player[len+0] = tesxx;
player[len+1] = '[=12=]';

或者,如其他答案之一所建议,您可以改用 strncat,这样您就可以将单个字符附加到字符串中:

strncat( player, &tesxx, 1 );

或者,您可以更改行

strcat(player, tesxx);
strcat(player, ot);
strcat(player, testt);
strcat(player, oty);

以下内容:

snprintf( player + 2, (sizeof player) - 2, "%c%s%c%s", tesxx, ot, testt, oty );

有关详细信息,请参阅函数 snprintf

如果不能保证这些行之前的字符串长度为 2,那么您可以这样写:

size_t len = strlen( player );
snprintf( player + len, (sizeof player) - len, "%c%s%c%s", tesxx, ot, testt, oty );

您还可以使用函数 snprintf:

构建整个字符串 player
    char player[1024];
    int tesx = 1;
    char tesxx = tesx + '0';
    char ot[] = ";";
    char oty[] = "H0";
    int test = 3;
    char testt = test + '0';
snprintf( player, sizeof player, "\x1b[%c%s%c%s", tesxx, ot, testt, oty );

strcat 接受 2 个字符串指针:

char *strcat(char *dest, const char *src);

strcat(player, tesxx)strcat(player, testt) 中,您传递 char 而不是 char *,调用未定义的行为。为了将单个字符附加到带有额外 space 的数组中的 C 字符串,您可以编写显式代码:

#include <string.h>

void append_char(char *dest, char c) {
    size_t len = strlen(dest);
    dest[len++] = c;
    dest[len] = '[=11=]';
}

或者您可以使用 <string.h> 中定义的 strncat 作为:

char *strncat(char *dest, const char *src, size_t n);

此函数最多在 dest 的末尾附加 src 中的 n 个字符。可以传一个char的地址和1的长度:

#include <string.h>

void append_char(char *dest, char c) {
    strncat(dest, &c, 1);
}

然而对于您的代码,使用起来似乎更简单 snprintf:

    char player[1024];  // probably too large
    int tesx = 1;
    int test = 3;
    consoleInit(GFX_TOP, NULL);
    // draw a `0` at screen coordinates tesx,test
    snprintf(player, sizeof player, "\x1b[%d;%dH0", tesx, test);