fgets正在返回一个空白屏幕

问题描述 投票:0回答:1

我是C的新手,这是我的第一个项目,并且一直在自学。在我的程序中,我的一个函数需要从文件中读取一行,并将其存储在char数组中。当我用gdb跟踪程序时,数组(line [])只是零。这导致我的程序返回错误“错误:资产文件中的一行缺少':'分隔符\ n”这是我的代码:

//return the line number (0 based) that the cmd is on, -1 if absent
int locateCmd(char cmd[]) {
        int lineIndex = -1;     //-1, because lineIndex is incramented before the posible return
        char cmdTemp[10] = "\0";

        //create a compareable cmd with correct cmd that has its remaining values zeroed out
        char cmdCmp[10] = "\0";
        memset(cmdCmp, 0, sizeof(cmdCmp));
        for (int i = 0; i < strlen(cmd); i++) {
                cmdCmp[i] = cmd[i];
        }

        FILE *file = fopen(ASSET_FILE, "r");

        //loop until target line is reached
        while (strcmp(cmdTemp, cmdCmp) != 0)  {
                //check if last line is read
                if (lineIndex == lineCounter(file)-1) {
                        return -1;
                }

                memset(cmdTemp, 0, sizeof(cmdTemp));
                char line[61];
                fgets(line, 61, file);
                //set cmdTemp to the command on current line
                lineIndex++;
                for (int i = 0; line[i] != ':'; i++) {
                        cmdTemp[i] = line[i];

                        //return error if line doesn't contain a ':'
                        if (line[i] = '\n') {
                        printf("Error: a line in the asset file lacks a ':' separator\n");
                        exit(1);
                        }
                }
        }

        return lineIndex;
}

在某些上下文中,此函数传递一个命令,其作用是读取如下所示的文档:

command:aBunchOfInfoOnTheComand
anotherCommand:aBunchOfInfoOnTheComand

并选出传递的命令(cmd [])存储的行。

问题在于第24行的fgets。我将这段代码的相关部分分成了一个较小的测试程序,它工作正常。有效的测试程序是:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (int argc, char *argv[]) {
    FILE *file = fopen("tutorInfo.txt", "r");
    char line[61];
    fgets(line, 61, file);
    printf("%s\n", line);
}

正确地说明我的测试程序导致我相信我的函数中的其他代码导致了问题,但我不确定是什么。值得注意的是,有问题的代码与我的示例程序具有相同的导入。任何帮助将非常感激。

c file fgets
1个回答
0
投票

由于OP没有提供Minimal, Complete, and Verifiable example,我必须根据问题中提供的功能描述作出答案。

我已经介绍了一些错误和角落案例,但我确定我错过了一些。该方法也是低效的,因为文件被反复读取,而不是解析它一次并返回散列/映射/目录以便于查找。在现实生活中的代码我会使用像GLib这样的东西,而不是浪费我的时间试图重新发明轮子......

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LINE_BUFFER_LENGTH 200

unsigned int locateCmd(FILE *fh, const char *key, const char **cmd_line) {
  unsigned int found = 0;
  size_t key_length = strlen(key);
  *cmd_line = NULL;

  /* make sure to start read from start of file */
  rewind(fh);

  unsigned int line_no = 0;
  static char buffer[LINE_BUFFER_LENGTH];
  while (!feof(fh) && (found == 0)) {
    // NOTE: EOF condition will be checked on the next iteration
    fgets(buffer, sizeof(buffer), fh);
    size_t length = strlen(buffer);
    line_no++;

    if (buffer[length - 1] != '\n') {
      printf("line %u is too long, aborting!\n", line_no);
      return(0);
    }

    if ((strncmp(key, buffer, key_length) == 0) &&
        (buffer[key_length] == ':')) {
      found              = line_no;
      buffer[length - 1] = '\0'; // strip line ending
      *cmd_line          = &buffer[key_length + 1];
    }
  }

  return(found);
}

int main(int argc, char *argv[]) {
  FILE *fh = fopen("dummy.txt", "r");
  if (!fh) {
    perror("file open");
    return(1);
  }

  int ret = 0;
  while (--argc > 0) {
    const char *cmd;
    const char *key  = *++argv;
    unsigned line_no = locateCmd(fh, key, &cmd);
    if (line_no != 0) {
      printf("key '%s' found on line %u: %s\n", key, line_no, cmd);
      ret = 0;
    } else {
      printf("key '%s' not found!\n", key);
    };
  }

  if (fclose(fh) != 0) {
    perror("file close");
    return(1);
  }

  return(ret);
}

测试输入dummy.txt

command:aBunchOfInfoOnTheComand
anotherCommand:aBunchOfInfoOnTheComand
brokenline

foo:bar
toolong:sadflkjaLKFJASDJFLKASJDFLKSAJ DLFKJ SLDKJFLKASDFASDFKJASKLDJFLKASJDFLKJASDLKFJASLKDFJLKASDJFLKASJDLFKJASDKLFJKLASDJFLKSAJDFLKJASDLKFJKLASDJFLKASJDFKLJASDLKFJLKASDJFLKASJDFLKJSADLKFJASLKDJFLKC

一些测试运行:

$ gcc -Wall -o dummy dummy.c
$ ./dummy command foo bar
key 'command' found on line 1: aBunchOfInfoOnTheComand
key 'foo' found on line 5: bar
line 6 is too long, aborting!
key 'bar' not found!
© www.soinside.com 2019 - 2024. All rights reserved.