【发布时间】:2021-12-23 04:44:32
【问题描述】:
我正在用 C 语言解决一个问题,我在内存中给出了代表两支球队之间比赛结果的字节序列,格式如下:"manchester 40 chelsea;chelsea 43 arsenal\0" 所以每个结果都以第一队的名字开头,然后是一个空格,然后他们的分数用一个字节表示,然后第二队的分数也以一个字节、另一个空格和第二队的名字表示。结果用分号分隔,但最后一个以'\0'结尾。这是我写的代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct {
char *team1;
int score1;
char *team2;
int score2;
} gameResult;
char *nameCopy(void* results, char terminate) {
char *ptr = (char*)results;
int len = 0;
while (*ptr != '\0' && *ptr != terminate) {
len++;
ptr++;
}
char *res = malloc(len + 1);
memcpy(res, results, len);
res[len] = '\0';
return res;
}
gameResult readGameResult(void* results) {
gameResult res;
char* ptr = (char*)results;
res.team1 = nameCopy(ptr, ' ');
ptr += strlen(res.team1) + 1;
res.score1 = *ptr;
ptr++;
res.score2 = *ptr;
res.team2 = nameCopy(ptr + 2, ';');
printf("%s, %d, %d, %s\n", res.team1, res.score1, res.score2, res.team2);
return res;
}
int main() {
// manchester 41 chelsea;chelsea 32 arsenal;arsenal 23 manchester\0
char results[63] = "manchester 04 chelsea;chelsea 32 arsenal;arsenal 23 manchester";
results[11] = 4;
results[12] = 0;
results[30] = 3;
results[31] = 2;
results[49] = 2;
results[50] = 3;
results[62] = '\0';
char *gres = strdup(results);
readGameResult(gres);
return 0;
}
我将单字节分数存储为字符似乎存在问题。该代码适用于每个实例,除非其中一个分数为 0。我猜这与 ascii 值 0 对应于空终止字符这一事实有关。但我仍然不明白为什么这会导致问题,因为res.team2 = nameCopy(ptr + 2, ';'); 行我应该超过 0 字符,但 nameCopy 函数似乎仍然收到指向“/0”的指针。上面的代码产生以下输出:
"manchester, 4, 0, \r\n"
【问题讨论】:
-
40不是一个字节,而是两个字节。 -
@Barmar 我知道吗?表示结果 4-0,其中 4 和 0 写入单个字节
-
您将 ASCII 字符代码存储在
score1和score2中,而不是数值 4 和 0。 -
我认为问题在于您没有显示的代码。
res.score1 = *ptr;让我认为您正在读取一个文件,并且该文件是由另一个代码生成的。将空字节写入文件没有任何问题,但必须谨慎行事。很抱歉,如果没有minimal reproducible example,我猜不出更多。 -
罪魁祸首是
char *gres = strdup(results);!strdup只会复制到第一个空字符,因此gres不是您results数组的完整副本。顺便说一句,作为一个字节值,0和'\0'是完全一样的东西......
标签: c pointers pointer-arithmetic