英文:
Reading a specific pattern of a txt file in C
问题
以下是您提供的内容的翻译:
我有一个带有以下模式的txt文件:
11/01/2010:没有通过考试!:(
5
10/02/2010:甚至这次我也没有通过!>:(
2
16/04/2010:这是我第三次重考这门考试!>:@
1
20/05/2024:终于通过了!:D
14
我必须将文件中的每个实例放入一个如下定义的队列数据结构中:
``` c
struct post {
char msg[257];
int n_like;
};
struct feed {
struct post* storage;
int busy;
};
void init(struct feed* queue) {
queue->storage = malloc(sizeof(struct post) * N_QUEUE); //N_QUEUE = 4
queue->busy = 0;
}
为此,我尝试了以下函数,在该函数中,我使用fgets()
读取第一整行,然后使用fscanf()
读取下面的数字。然后通过append()
存储所有内容:
int append(struct feed* queue, struct post s) {
if (queue->busy >= N_QUEUE) return handle_err(FULL);
queue->storage[queue->busy] = s;
queue->busy++;
return OK;
}
struct post pop(struct feed* queue) {
if (queue->busy <= 0) handle_err(EMPTY);
struct post s = queue->storage[0];
for (int i = 0; i < queue->busy - 1; i++) {
queue->storage[i] = queue->storage[i + 1];
}
queue->busy--;
return s;
}
int load_user_from_file(char* filename, struct feed* queue) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) return handle_err(FILE_ERR);
struct post s;
while (fgets(s.msg, 257, fp) != NULL) {
while (fscanf(fp, "%d", &s.n_like) == 1) {
append(&(*queue), s);
}
}
return OK;
}
主函数:
int main() {
struct feed queue;
init(&queue);
char* filename = "user42.txt";
load_user_from_file(filename, &queue);
return 0;
}
如果我让程序运行,我当然会得到空字符串和零。但是,如果包括handle_err()
,该函数只会在屏幕上触发错误并退出。
int handle_err(int errno) {
switch (errno) {
case FILE_ERR:
printf("\nerror (%d): 无法写入/读取文件\n\n", FILE_ERR);
break;
case EMPTY:
printf("\nerror (%d): 队列为空\n\n", EMPTY);
break;
case FULL:
printf("\nerror (%d): 队列已达到其最大容量\n\n", FULL);
break;
default: printf("\n发生未知错误\n\n");
}
exit(FALSE);
}
我相当确定load_user_from_file
函数中有问题。
英文:
I have a txt file with this pattern:
11/01/2010: did not pass the test! :(
5
10/02/2010: not even this time I passed it! >:(
2
16/04/2010: is the third time I retake this exam!!! >:@
1
20/05/2024: finally passed it! :D
14
I have to put every instance in the file in a queue data structure so defined
struct post {
char msg[257];
int n_like;
};
struct feed {
struct post* storage;
int busy;
};
void init(struct feed* queue) {
queue->storage = malloc(sizeof(struct post) * N_QUEUE); //N_QUEUE = 4
queue->busy = 0;
}
To do this I tried this function, where I read the first whole line using fgets()
and then the number below with fscanf()
. Then storing everythin through append()
:
int append(struct feed* queue, struct post s) {
if (queue->busy >= N_QUEUE) return handle_err(FULL);
queue->storage[queue->busy] = s;
queue->busy++;
return OK;
}
struct post pop(struct feed* queue) {
if (queue->busy <= 0) handle_err(EMPTY);
struct post s = queue->storage[0];
for (int i=0; i<queue->busy-1; i++) {
queue->storage[i] = queue->storage[i+1];
}
queue->busy--;
return s;
}
int load_user_from_file(char* filename, struct feed* queue) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) return handle_err(FILE_ERR);
struct post s;
while (fgets(s.msg, 257, fp) != NULL) {
while (fscanf(fp, "%d", &s.n_like) == 1) {
append(&(*queue), s);
}
}
return OK;
}
main:
int main() {
struct feed queue;
init(&queue);
char* filename = "user42.txt";
load_user_from_file(filename, &queue);
return 0;
}
If I let the program run I get, of course, empty strings and zeros. Instead by including the handle_err()
, which just triggers errors on screen and exits, I get a full stack error.
int handle_err(int errno) {
switch (errno) {
case FILE_ERR:
printf("\nerror (%d): could not write/read the file\n\n", FILE_ERR);
break;
case EMPTY:
printf("\nerror (%d): queue is empty\n\n", EMPTY);
break;
case FULL:
printf("\nerror (%d): queue reached its full space\n\n", FULL);
break;
default: printf("\nunknown error occurred\n\n");
}
exit(FALSE);
}
I'm pretty sure there's something wrong in the load_user_from_file
function.
答案1
得分: 1
Your code is incomplete, but the corrected portion is as follows:
while (fgets(s.msg, 257, fp) != NULL)
{
char buf[100];
if ( (fgets(buf, sizeof(buf), fp) != NULL)
&& (sscanf(buf, "%d", &s.n_like) == 1)
{
append(&(*queue), s);
}
else
{ // Adjust error handling for your needs.
exit(1);
}
}
Please note that this code corrects the issue with fscanf
and parses the input as intended.
英文:
While your code is not complete, this is clearly wrong:
while (fgets(s.msg, 257, fp) != NULL) {
while (fscanf(fp, "%d", &s.n_like) == 1) {
append(&(*queue), s);
}
}
With the given input file that will result in more entries than you want to.
With
11/01/2010: did not pass the test! :(
5
10/02/2010: not even this time I passed it! >:(
2
The fscanf
will first parse 5
and then also 10
, leaving "/02/2010: not even this time I passed it! >:(\n"
for the next entry.
In total you will append 7 structs instead of 4.
As you have a clear relation of one line with date+text and one line with that integer, it does not make any sense to use fscanf
in a loop.
Try something like this:
while (fgets(s.msg, 257, fp) != NULL)
{
char buf[100];
if ( (fgets(buf, sizeof(buf), fp) != NULL)
&& (sscanf(buf, "%d", &s.n_like) == 1)
{
append(&(*queue), s);
}
else
{ // Adjust error handling for your needs.
exit(1);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论