[英]printf char array in structure also prints next int in C
I am very new to C and I don't know that much about it, although I do have some experience with programming as a whole.我对 C 非常陌生,我对此知之甚少,尽管我确实有一些编程方面的整体经验。 Whenever I get warnings or errors I just look it up online.
每当我收到警告或错误时,我都会在网上查找。 But this one doesn't give a warning or an error.
但是这个没有给出警告或错误。 It runs fine but it gives the wrong result.
它运行良好,但给出了错误的结果。
So I have a structure with a char[16] and 2 ints:所以我有一个带有 char[16] 和 2 个整数的结构:
struct tile {
char layout[16];
int arrowClr;
int spPlacing;
};
I make an array of 200 of them with struct tile tiles[200];
我用
struct tile tiles[200];
制作了一个由 200 个组成的数组struct tile tiles[200];
. . Then I open a file with a list of characters & numbers:
然后我打开一个包含字符和数字列表的文件:
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");
This is the list:这是清单:
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
After that, I cycle through each line, storing the 16 first characters in the structure layout char (I used sprintf to make it know it was a character, because otherwise it just gave ascii value) and the last two numbers in the two ints:之后,我循环遍历每一行,在结构布局 char 中存储前 16 个字符(我使用 sprintf 使其知道它是一个字符,否则它只给出 ascii 值)和两个 int 中的最后两个数字:
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];
}
Then, I display each of them to test it (without the two ints) with:然后,我显示它们中的每一个以测试它(没有两个整数):
for (int i=0;i<21;i++) {
printf("%s\n",tiles[i].layout);
}
And this is the result:这是结果:
w s d d w2
wwwww w s w w1
w wws ww ww w1
w ww ww sww w1
w sw w w2
ws ww ww ww w2
wwww w w w1
ws w w w 2
wwwww w sw 2
w ww dws dw w1
wwww s 2
w ww sww ww w1
wwww w s w w2
wddw sw w w1
wwww s 2
w wd swd ww w2
w w s w w2
wddww w s w 2
wddww sww ww w2
w ww wws ww w1
wwww w ww w1
Removing the tiles[i].arrowClr = buf[16];
移除
tiles[i].arrowClr = buf[16];
makes that last number disappear from each line, and making the for loop before it go while e<15
instead of e<16
makes it disappear too, also making the last character before it vanish too.使最后一个数字从每一行消失,并在它之前进行 for 循环而
e<15
而不是e<16
使它也消失,也使最后一个字符消失之前。
BTW I know tiles[i].arrowClr = buf[16];
顺便说一句,我知道
tiles[i].arrowClr = buf[16];
& tiles[i].spPlacing = buf[17];
&
tiles[i].spPlacing = buf[17];
give me the ascii values of the numbers, that's just another problem, if anybody knows how to fix that too that would be useful给我数字的 ascii 值,这只是另一个问题,如果有人也知道如何解决这个问题,那会很有用
layout[16] = '\\0'
arrowClr = buf[16] - '0';
In this line在这一行
printf("%s\n",tiles[i].layout);
there is expected to be a string terminator '\\0'
at the end of the string.字符串末尾应该有一个字符串终止符
'\\0'
。 But you didn't put one.但是你没有放一个。 You built the string like this
你像这样构建了字符串
for (int e=0;e<16;e++) {
sprintf(&tiles[i].layout[e],"%c",buf[e]);
...
Your struct definition needs an extra char length您的结构定义需要额外的字符长度
char layout[17]; // <--- 16 to 17
and then after copying chars from the file, you need然后从文件复制字符后,你需要
tiles[i].layout[16] = '\0';
to terminate the string so you can print it.终止字符串,以便您可以打印它。
Then, the last two fields which you obtain with然后,您获得的最后两个字段
tiles[i].arrowClr = buf[16];
tiles[i].spPlacing = buf[17];
should be like this, to convert the single digit ASCII value to an int
type应该是这样,将一位数的ASCII值转换为
int
类型
tiles[i].arrowClr = buf[16] - '0';
tiles[i].spPlacing = buf[17] - '0';
asuming that you intended the read value to be the number 1
or 2
and not the character '1'
or '2'
.假设您希望读取的值是数字
1
或2
而不是字符'1'
或'2'
。
As I and others mentioned, you need to allocate at least one more byte to your string.正如我和其他人提到的,您需要为您的字符串至少再分配一个字节。 But I would also recommend replacing your for loop (%c) with a simple call to
snprintf()
.但我也建议用对
snprintf()
的简单调用替换你的 for 循环 (%c snprintf()
。 That will let you specify the 16 bytes you want from buf
.这将允许您从
buf
指定您想要的 16 个字节。
You need a nul character ( '\\0'
) at the end of your string if you want to use it with standard C string functions.如果要将空字符 (
'\\0'
) 与标准 C 字符串函数一起使用,则字符串末尾需要一个空字符 ( '\\0'
)。
Arrays in C don't have any length information associated with them, so in order for printf
to know when it's reached the end of a string it needs some sort of marker. C 中的数组没有任何与它们相关的长度信息,因此为了让
printf
知道它何时到达字符串的末尾,它需要某种标记。 The nul character is used for this (also by all other string related functions like strlen
, strcpy
, etc.). nul 字符用于此(也由所有其他与字符串相关的函数,如
strlen
、 strcpy
等)。
You're using the layout
field as an array of characters, but you're trying to print it as a string.您将
layout
字段用作字符数组,但您试图将其打印为字符串。 In C a string is a NULL terminated array of characters.在 C 中,字符串是以 NULL 结尾的字符数组。 Since your array doesn't have a NULL terminator,
printf
keeps looking until it finds a 0 byte, which it ends up finding in the arrowClr
field which is laid out next in memory.由于您的数组没有 NULL 终止符,
printf
会继续查找,直到找到 0 字节,最终会在内存中的下一个arrowClr
字段中找到该字节。 That's why it's printing out the number.这就是它打印出数字的原因。
You need to either make layout
one character bigger, ie char layout[17]
, and set layout[16] = 0
, or you would need to run printf
in a loop to print each character individually.您需要使
layout
一个字符,即char layout[17]
,并设置layout[16] = 0
,或者您需要在循环中运行printf
以单独打印每个字符。 I'd recommend the former.我推荐前者。
To get the numerical values of the last two characters, you need to do this:要获取最后两个字符的数值,您需要这样做:
tiles[i].arrowClr = buf[16] - '0';
tiles[i].spPlacing = buf[17] - '0';
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.