在C中读取特定模式的txt文件

huangapple go评论73阅读模式
英文:

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! &gt;:(
2
16/04/2010: is the third time I retake this exam!!! &gt;:@
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-&gt;storage = malloc(sizeof(struct post) * N_QUEUE); //N_QUEUE = 4
	queue-&gt;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-&gt;busy &gt;= N_QUEUE) return handle_err(FULL);
	queue-&gt;storage[queue-&gt;busy] = s;
	queue-&gt;busy++;
	return OK;
}

struct post pop(struct feed* queue) {
	if (queue-&gt;busy &lt;= 0) handle_err(EMPTY);
	struct post s = queue-&gt;storage[0];
	for (int i=0; i&lt;queue-&gt;busy-1; i++) {
		queue-&gt;storage[i] = queue-&gt;storage[i+1];
	}
	queue-&gt;busy--;
	return s;
}

int load_user_from_file(char* filename, struct feed* queue) {
	FILE *fp = fopen(filename, &quot;r&quot;);
	if (fp == NULL) return handle_err(FILE_ERR);
	
	struct post s;
	while (fgets(s.msg, 257, fp) != NULL) {
			while (fscanf(fp, &quot;%d&quot;, &amp;s.n_like) == 1) {
				append(&amp;(*queue), s);
			}
		}
	return OK;
}

main:

int main() {
	struct feed queue;
	init(&amp;queue);
	char* filename = &quot;user42.txt&quot;; 
	load_user_from_file(filename, &amp;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(&quot;\nerror (%d): could not write/read the file\n\n&quot;, FILE_ERR);
			break;
		case EMPTY:
			printf(&quot;\nerror (%d): queue is empty\n\n&quot;, EMPTY);
			break;
		case FULL:
			printf(&quot;\nerror (%d): queue reached its full space\n\n&quot;, FULL);
			break;
		default: printf(&quot;\nunknown error occurred\n\n&quot;);
	}
	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, &quot;%d&quot;, &amp;s.n_like) == 1) {
                append(&amp;(*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! &gt;:(
2

The fscanf will first parse 5 and then also 10, leaving &quot;/02/2010: not even this time I passed it! &gt;:(\n&quot; 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) 
          &amp;&amp; (sscanf(buf, &quot;%d&quot;, &amp;s.n_like) == 1)
        {
           append(&amp;(*queue), s);
        }
        else
        {   // Adjust error handling for your needs.
            exit(1);
        }
    }

huangapple
  • 本文由 发表于 2023年6月12日 18:32:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76455781.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定