结构中的printf char数组也会在C中打印下一个int
我对C非常陌生,对它了解不多,虽然我对整个编程有一些经验。每当我收到警告或错误时,我只是在网上查找。但这个并没有给出警告或错误。它运行正常,但给出了错误的结果 所以我有一个结构,有一个char[16]和两个int:结构中的printf char数组也会在C中打印下一个int,c,C,我对C非常陌生,对它了解不多,虽然我对整个编程有一些经验。每当我收到警告或错误时,我只是在网上查找。但这个并没有给出警告或错误。它运行正常,但给出了错误的结果 所以我有一个结构,有一个char[16]和两个int: struct tile { char layout[16]; int arrowClr; int spPlacing; }; 我用struct-tile-tiles[200]制作了一个200个数组。然后我打开一个包含字符和数字列表的文件: char resourceName[5];
struct tile {
char layout[16];
int arrowClr;
int spPlacing;
};
我用struct-tile-tiles[200]制作了一个200个数组代码>。然后我打开一个包含字符和数字列表的文件:
char resourceName[5];
scanf("%s",&*resourceName);
char rLoc[100];
sprintf(rLoc,"Resources/%s/",resourceName);
char tileLoc[100];
sprintf(tileLoc,"%sTiles.txt",rLoc);
FILE *tile_list;
tile_list = fopen(tileLoc,"r");
名单如下:
w s d d w20
wwwww w s w w10
w wws ww ww w10
w ww ww sww w10
w sw w w20
ws ww ww ww w21
wwww w w w10
ws w w w 20
wwwww w sw 20
w ww dws dw w10
wwww s 20
w ww sww ww w11
wwww w s w w20
wddw sw w w10
wwww s 20
w wd swd ww w20
w w s w w20
wddww w s w 20
wddww sww ww w20
w ww wws ww w10
wwww w ww w10
之后,我循环每一行,存储结构布局字符中的前16个字符(我使用sprintf让它知道这是一个字符,因为否则它只给出ascii值)和两个整数中的最后两个数字:
for (int i=0;fgets(buf,100,tile_list)!=NULL;i++) {
strtok(buf,"\n");
//printf("%s",buf);
//printf("%c\n",buf[0]);
for (int e=0;e<16;e++) {
sprintf(&tiles[i].layout[e],"%c",buf[e]);
}
tiles[i].arrowClr = buf[16];
tiles[i].spPlacing = buf[17];
}
移除平铺[i]。箭头CLR=buf[16]代码>使最后一个数字从每行中消失,并使for循环在它消失之前,而e
终止布局字符串时不能为null。如果这个字符串是has
16个字符,将一个字符添加到布局数组中以获取空值<代码>布局[16]
='\0'
如果这是您的意图,您需要将ASCII字符串转换为数字<代码>箭头CLR=buf[16]-“0”代码>
在这一行
printf("%s\n",tiles[i].layout);
字符串的末尾应该有一个字符串终止符'\0'
。但你没有放一个。你是这样做的
for (int e=0;e<16;e++) {
sprintf(&tiles[i].layout[e],"%c",buf[e]);
...
终止字符串以便打印它
然后,使用
tiles[i].arrowClr = buf[16];
tiles[i].spPlacing = buf[17];
应该是这样的,将一位数ASCII值转换为int
类型
tiles[i].arrowClr = buf[16] - '0';
tiles[i].spPlacing = buf[17] - '0';
如果您希望读取的值是数字1
或2
,而不是字符'1'
或'2'
,如我和其他人所述,则需要为字符串至少分配一个字节。但我也建议用对snprintf()
的简单调用替换for循环(%c)。这将允许您从buf
中指定所需的16个字节。如果要将其与标准C字符串函数一起使用,则需要在字符串末尾添加nul字符('\0'
)
C中的数组没有任何与之相关的长度信息,因此为了让printf
知道何时到达字符串的末尾,它需要某种标记。nul字符用于此操作(也可由所有其他与字符串相关的函数使用,如strlen
,strcpy
,等等)。您将布局
字段用作字符数组,但尝试将其作为字符串打印。在C语言中,字符串是以NULL结尾的字符数组。由于您的数组没有空终止符,printf
会一直查找,直到找到一个0字节,最后在内存中下一个列出的arrowClr
字段中找到该字节。这就是为什么它要打印号码
您需要将layout
增大一个字符,即char layout[17]
,并将layout[16]=0
,或者需要在循环中运行printf
,以单独打印每个字符。我推荐前者
要获取最后两个字符的数值,需要执行以下操作:
tiles[i].arrowClr = buf[16] - '0';
tiles[i].spPlacing = buf[17] - '0';
您正在为要打印的字符串(C字符串)指定格式化程序。预期字符串的结尾应包含终止null。但您的布局字段不包含一个。我真的很惊讶我得到答案的速度有多快。我通常需要等几天才能在论坛上得到答案。是因为堆栈溢出真的很流行吗?它不仅仅是流行。结构的某些方面导致了高质量的答案。我认为开发人员在提供一个好的公认答案时会得到精神上的鼓舞。在某种程度上,声誉点的作用类似于分数。@technosaurus我的回答要求此人在数组中为空值添加一个。如果完成,布局的大小现在是17。你大概是说“不是”而不是“是”。请校对您的答案,尤其是那些颠倒意思的错误。atoi()
需要字符串,而不是字符。不过,这是个好主意。通常,库调用得到更好的支持(并且可以移植)。
tiles[i].layout[16] = '\0';
tiles[i].arrowClr = buf[16];
tiles[i].spPlacing = buf[17];
tiles[i].arrowClr = buf[16] - '0';
tiles[i].spPlacing = buf[17] - '0';
tiles[i].arrowClr = buf[16] - '0';
tiles[i].spPlacing = buf[17] - '0';