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

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

Reading a specific pattern of a txt file in C

问题

以下是您提供的内容的翻译:

  1. 我有一个带有以下模式的txt文件

11/01/2010:没有通过考试!:(
5
10/02/2010:甚至这次我也没有通过!>:(
2
16/04/2010:这是我第三次重考这门考试!>:@
1
20/05/2024:终于通过了!:D
14

  1. 我必须将文件中的每个实例放入一个如下定义的队列数据结构中:
  2. ``` c
  3. struct post {
  4. char msg[257];
  5. int n_like;
  6. };
  7. struct feed {
  8. struct post* storage;
  9. int busy;
  10. };
  11. void init(struct feed* queue) {
  12. queue->storage = malloc(sizeof(struct post) * N_QUEUE); //N_QUEUE = 4
  13. queue->busy = 0;
  14. }

为此,我尝试了以下函数,在该函数中,我使用fgets()读取第一整行,然后使用fscanf()读取下面的数字。然后通过append()存储所有内容:

  1. int append(struct feed* queue, struct post s) {
  2. if (queue->busy >= N_QUEUE) return handle_err(FULL);
  3. queue->storage[queue->busy] = s;
  4. queue->busy++;
  5. return OK;
  6. }
  7. struct post pop(struct feed* queue) {
  8. if (queue->busy <= 0) handle_err(EMPTY);
  9. struct post s = queue->storage[0];
  10. for (int i = 0; i < queue->busy - 1; i++) {
  11. queue->storage[i] = queue->storage[i + 1];
  12. }
  13. queue->busy--;
  14. return s;
  15. }
  16. int load_user_from_file(char* filename, struct feed* queue) {
  17. FILE *fp = fopen(filename, "r");
  18. if (fp == NULL) return handle_err(FILE_ERR);
  19. struct post s;
  20. while (fgets(s.msg, 257, fp) != NULL) {
  21. while (fscanf(fp, "%d", &s.n_like) == 1) {
  22. append(&(*queue), s);
  23. }
  24. }
  25. return OK;
  26. }

主函数:

  1. int main() {
  2. struct feed queue;
  3. init(&queue);
  4. char* filename = "user42.txt";
  5. load_user_from_file(filename, &queue);
  6. return 0;
  7. }

如果我让程序运行,我当然会得到空字符串和零。但是,如果包括handle_err(),该函数只会在屏幕上触发错误并退出。

  1. int handle_err(int errno) {
  2. switch (errno) {
  3. case FILE_ERR:
  4. printf("\nerror (%d): 无法写入/读取文件\n\n", FILE_ERR);
  5. break;
  6. case EMPTY:
  7. printf("\nerror (%d): 队列为空\n\n", EMPTY);
  8. break;
  9. case FULL:
  10. printf("\nerror (%d): 队列已达到其最大容量\n\n", FULL);
  11. break;
  12. default: printf("\n发生未知错误\n\n");
  13. }
  14. exit(FALSE);
  15. }

我相当确定load_user_from_file函数中有问题。

英文:

I have a txt file with this pattern:

  1. 11/01/2010: did not pass the test! :(
  2. 5
  3. 10/02/2010: not even this time I passed it! &gt;:(
  4. 2
  5. 16/04/2010: is the third time I retake this exam!!! &gt;:@
  6. 1
  7. 20/05/2024: finally passed it! :D
  8. 14

I have to put every instance in the file in a queue data structure so defined

  1. struct post {
  2. char msg[257];
  3. int n_like;
  4. };
  5. struct feed {
  6. struct post* storage;
  7. int busy;
  8. };
  9. void init(struct feed* queue) {
  10. queue-&gt;storage = malloc(sizeof(struct post) * N_QUEUE); //N_QUEUE = 4
  11. queue-&gt;busy = 0;
  12. }

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():

  1. int append(struct feed* queue, struct post s) {
  2. if (queue-&gt;busy &gt;= N_QUEUE) return handle_err(FULL);
  3. queue-&gt;storage[queue-&gt;busy] = s;
  4. queue-&gt;busy++;
  5. return OK;
  6. }
  7. struct post pop(struct feed* queue) {
  8. if (queue-&gt;busy &lt;= 0) handle_err(EMPTY);
  9. struct post s = queue-&gt;storage[0];
  10. for (int i=0; i&lt;queue-&gt;busy-1; i++) {
  11. queue-&gt;storage[i] = queue-&gt;storage[i+1];
  12. }
  13. queue-&gt;busy--;
  14. return s;
  15. }
  16. int load_user_from_file(char* filename, struct feed* queue) {
  17. FILE *fp = fopen(filename, &quot;r&quot;);
  18. if (fp == NULL) return handle_err(FILE_ERR);
  19. struct post s;
  20. while (fgets(s.msg, 257, fp) != NULL) {
  21. while (fscanf(fp, &quot;%d&quot;, &amp;s.n_like) == 1) {
  22. append(&amp;(*queue), s);
  23. }
  24. }
  25. return OK;
  26. }

main:

  1. int main() {
  2. struct feed queue;
  3. init(&amp;queue);
  4. char* filename = &quot;user42.txt&quot;;
  5. load_user_from_file(filename, &amp;queue);
  6. return 0;
  7. }

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.

  1. int handle_err(int errno) {
  2. switch (errno) {
  3. case FILE_ERR:
  4. printf(&quot;\nerror (%d): could not write/read the file\n\n&quot;, FILE_ERR);
  5. break;
  6. case EMPTY:
  7. printf(&quot;\nerror (%d): queue is empty\n\n&quot;, EMPTY);
  8. break;
  9. case FULL:
  10. printf(&quot;\nerror (%d): queue reached its full space\n\n&quot;, FULL);
  11. break;
  12. default: printf(&quot;\nunknown error occurred\n\n&quot;);
  13. }
  14. exit(FALSE);
  15. }

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:

  1. while (fgets(s.msg, 257, fp) != NULL)
  2. {
  3. char buf[100];
  4. if ( (fgets(buf, sizeof(buf), fp) != NULL)
  5. && (sscanf(buf, "%d", &s.n_like) == 1)
  6. {
  7. append(&(*queue), s);
  8. }
  9. else
  10. { // Adjust error handling for your needs.
  11. exit(1);
  12. }
  13. }

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:

  1. while (fgets(s.msg, 257, fp) != NULL) {
  2. while (fscanf(fp, &quot;%d&quot;, &amp;s.n_like) == 1) {
  3. append(&amp;(*queue), s);
  4. }
  5. }

With the given input file that will result in more entries than you want to.

With

  1. 11/01/2010: did not pass the test! :(
  2. 5
  3. 10/02/2010: not even this time I passed it! &gt;:(
  4. 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:

  1. while (fgets(s.msg, 257, fp) != NULL)
  2. {
  3. char buf[100];
  4. if ( (fgets(buf, sizeof(buf), fp) != NULL)
  5. &amp;&amp; (sscanf(buf, &quot;%d&quot;, &amp;s.n_like) == 1)
  6. {
  7. append(&amp;(*queue), s);
  8. }
  9. else
  10. { // Adjust error handling for your needs.
  11. exit(1);
  12. }
  13. }

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:

确定