gpt4 book ai didi

c - 获取文本文件的每个元素,直到“:”并存储在struct变量中

转载 作者:太空宇宙 更新时间:2023-11-04 04:19:32 26 4
gpt4 key购买 nike

我需要帮助:/
在textfile上,我有这样的东西:
我的名字:15 3
我想读取每个元素直到“:”,并将其存储在结构的变量名中,然后读取下一个元素并将15和3存储在另一个变量中。

typedef struct STRUCT_PLAYER{char name[20];
int sucess;
int numQuest;
int wrongs;} PLAYER;


int readTop(PLAYER playTop[]){
char *classify = "classificacao.txt";
FILE *fl;
fl = fopen(classify, "r");

char c;
int n=0;

if(cl==NULL){
printf("Error reading the file %s\n", classify);
exit(1);
}
else{
while(c!=EOF){
while(c!=':'){
c=getc(fl);
if(c!=':') playTop[n].name=c;
}
if(c==':')fscanf(fl, " %d %d\n", &playTop[n].numQuest, &playTop[n].wrongs);

n++;

}

}
return n;

这是我的代码,但在这一行上似乎有个错误
如果(c!=':')播放程序停止[n].nome=c;
错误:为数组类型的表达式赋值
但我不明白是什么

最佳答案

ccharplayTop->namechar[],因此您正在分配不兼容的类型。阿尔索
coderredocanswer
数组名不是可修改的左值
初始化结构时,请执行以下操作:

int n=0;
playTop[n].name[0] = 0;

...

while(c!=':'){
char cs[] = { getc(fl), 0 };
if(c!=':')
strcat(playTop[n].name, cs);
}

其中 cs是一个C字符串,只包含一个字母,并且 strcat附加
将字符串设置为 playTop[n].name,从而保存名称
编辑
里卡多的评论
谢谢您。但我不明白你为什么把0放在 char cs[] = { getc(fl), 0}
这就是我在评论中所说的。在C中,字符串必须是
'\0'-终止。
C字符串是字节序列。此序列必须以值0结尾。
序列中的每个值都表示基于
ASCII编码,例如
字符 'a'是97, 'b'是98,等等
值0是决定字符串结尾的字符。
这就是为什么你经常听到C字符串以“\0”结尾的原因。
在C语言中,使用一个字符数组( '\0'char string[])来
保存字符串。对于长度为n的字符串,需要维度为n+1的数组,因为
您还需要一个空格作为结束字符。
在处理字符串时,总是要考虑合适的类型,
无论您使用的是数组还是指针。指针
to char并不一定意味着你在处理一个C字符串!
让我们看看
char str1[] = "Hallo";
char str2[] = { 'H', 'a', 'l', 'l', 'o', 0 };

两个声明都做同样的事情,它们初始化数组 char string[SOME VALUE]并且
'\0'有6个元素。 str1str2将相同:0(或 str1[5]
在其 str2[5]符号中)。
字符串文字是用引号括起来的文本, '\0'是字符串
字面意义的。链接器将序列放在进程的内存中的某个位置
char内存中,通常为只读内存(注意0
最后)。即使您没有显式地编写 "Hello",它也将
一个。
在序列末尾的“ 'H', 'a', 'l', 'l', 'o', 0”使序列成为
C字符串,而不是变量的类型。如果结尾没有“ '\0'”,则它不是C字符串。
char cs[] = { getc(fl), 0};


char cs[2];
cs[0] = getc(fl);
cs[1] = '\0';

通过执行最后的赋值,我确保 \0包含一个C字符串。大多数
char(标准库)中定义的函数需要C字符串,因此
必须 \0-终止。
人力资源部
  #include <string.h>

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

说明
cs函数将 string.h字符串附加到 '\0'字符串,
覆盖 strcat()结尾处的终止空字节( src),以及
然后添加一个终止的空字节。
从描述中可以看出 dest'\0'都必须是字符串,
因此, dest终止。所以我说你应该初始化
dest为0,因此这将是一个有效(且为空)字符串。只有
然后我可以使用 src
幸运的是,有很多方法可以存档相同的结果。如果你不想
使用 '\0'也可以这样做:
int name_idx = 0;
while(c!=EOF){
while(c!=':'){
c=getc(fl);
if(c!=':') playTop[n].name[name_idx++]=c;
}
if(c == ':')
{
// make sure that playTop[n].name is a c-string
playTop[n].name[name_idx] = 0;
fscanf(...);
}
...
}

最后一件事:
使用数组保存字符串还不错,问题是
字符串的最大长度为“cc>”。在你的情况下
名称不能超过19个字符,否则将有一个缓冲区
溢出,将重写未分配给
name,你会有不确定的行为,任何事情都有可能发生。
当您知道字符串的最大长度不会传递特定值时
(假设是15),那么就可以使用 playTop->name[0]。如果没有保证
最大长度,则必须使用
strcat/ strcat(以后您必须释放该内存)。
另外,解析行的更好方法是使用 dimension or array - 1获取while
行,然后分析它:
typedef struct STRUCT_PLAYER{char *name;
int sucess;
int numQuest;
int wrongs;} PLAYER;


int readTop(PLAYER playTop[]){
...
char line[1024];
fgets(line, sizeof line, fl);

int colon_index = strchr(line, ':');

// color_index is the index where : is in the line,
// the length of the name is colon_index - 1
// because you have to save \0 as well, you need to
// allocate one more space for the c-string
// name length + 1 ==> (colon_index - 1) + 1
// which equeals to colon_index
playTop[n].name = malloc(colon_index);

// copy the name from line into name. strncpy
// copies at most `colon_index - 1` characters, if
// \0 is not among them, it won't be appended at the end
// you have to do that
strncpy(playTop[n].name, line, colon_index - 1);

// making sure that name becomes a c-string
playTop[n].name[colon_index] = 0;

// sscanf is like fscan, only it takes the content from
// a string and not from a FILE object.
// line + colon_index + 1 ensures that sscanf reads only
// after the colon
sscanf(line + colon_index + 1, "...", ...);
}

这样做,可以确保名称可以有任何长度。请注意
所有这些函数都可能失败:例如,如果
内存不足,如果冒号不是
在行中找到(行格式错误或为空)。线路本身可能是
超过1024字节。为了简单起见,我省略了所有那些支票。
如果你理解我的代码,那么你可以通过检查
上面提到的错误。仔细阅读功能文档
用在这里。

关于c - 获取文本文件的每个元素,直到“:”并存储在struct变量中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48129369/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com