1

我正在使用一些带有嵌入式设备的 C,目前正在测试一些代码以从 SD 卡读取文件详细信息。我正在使用专有 API,但我会尽可能地删除它。

与其解释,我将尝试让代码自己说话:

 char* getImage() {
  int numFiles = //number of files on SD card
  for(int i=0; i<numFiles;i++) {
    \\lists the first file name in root of SD
    char *temp = SD.ls(i, 1, NAMES);
      if(strstr(temp, ".jpg") && !strstr(temp, "_")) {
        return temp;
      }
  }
  return NULL;
}

void loop()
{
  \\list SD contents
  USB.println(SD.ls());
  const char * image = getImage();
  if(image != NULL) {
    USB.println("Found an image!");
    USB.println(image);
    int byte_start = 0;
    USB.print("Image Size: ");
    **USB.println(SD.getFileSize(image));
    USB.println(SD.getFileSize("img.jpg"));**
}

底部的两行是麻烦的。如果我传递一个文字字符串,那么我会完美地获得文件大小。但是,如果我传递字符串(由图像变量表示),那么我会得到一个光荣的 -1。任何想法为什么?

为清楚起见,打印出来的图像确实显示了正确的文件名。

编辑:我知道在 C 中返回一个 char 并更好地修改传递给函数的变量是不受欢迎的。我也使用了这种方法,下面是代码示例,结果相同:

char * image = NULL;
getSDImage(&image, sizeof(image));
void getSDImage(char ** a, int length) {
  int numFiles = SD.numFiles();
  for(int i=0; i<numFiles;i++) {
    char *temp = SD.ls(i, 1, NAMES);
      if(strstr(temp, ".jpg") && !strstr(temp, "_")) {
        *a = (char*)malloc(sizeof(char) * strlen(temp));
        strcpy(*a, temp);
      }
  }
}

编辑 2:条目的链接在这里:SD.ls和文件大小函数的链接:SD.getFileSize

从返回来看,问题似乎出在文件大小函数上,因为返回是 -1(不是 0),并且在列出 SD 的根目录时会返回结果。

谢谢!

更新:我添加了一个空终止字符串的检查(这似乎是一个问题),这已在 getSDImage 函数中得到解决,具有以下内容:

        void getSDImage(char ** a, int length) {
      int numFiles = SD.numFiles();
      for(int i=0; i<numFiles;i++) {
        char *temp = SD.ls(i, 1, NAMES);
          if(strstr(temp, ".jpg") && !strstr(temp, "_")) {
            *a = (char*)malloc(sizeof(char) * strlen(temp));
            strncpy(*a, temp, strlen(temp)-1);
            *a[strlen(*a)-1] = '\0';
          }
      }
}

这似乎有效,我的标准输出结果很好,大小现在不显示为错误指示 -1 而是 -16760。我想我应该发布更新,以防有人有任何想法,但我的假设是这与文件名字符串有关。

4

2 回答 2

1

您的代码有几处可能有问题:
1)您可能传递了“不可见”字符,例如空格。请确保您传递的字符串完全相同,即逐个字符打印,包括空终止,并查看它们是否相同。
2) API 返回的值和其他 API 使用的值可能与预期不同。我建议(如果可能的话)您查看 API 源代码。如果您可以编译 API 本身,那么应该很容易找到问题(检查 API getFileSize() 从参数中得到什么)。根据您发送的 API 文档,检查buffer[DOS_BUFFER_SIZE]您从中获得 -1 后存储的值。

编辑(在查看 API 源代码之后):
在第 00657 行 func find_file_in_dir)你有:
if(strcmp(dir_entry->long_name, name) == 0)
这似乎是你在使用字符串时会有不同回复的唯一原因文字而不是从您的函数中获取名称。因此,您很可能没有传递相同的值(即,您要么传递不可见的字符,要么缺少字符串终止)。
最后一点:在每个代码到 SD API 之前检查缓冲区 [DOS_BUFFER_SIZE] 的内容。

我希望这有帮助。

亲切的问候,

于 2012-05-28T09:07:11.313 回答
0

这:

  if(strstr(temp, ".jpg") && !strstr(temp, "_")) {
    *a = (char*)malloc(sizeof(char) * strlen(temp));
    strcpy(*a, temp);
  }

坏了,它没有为终结器分配空间并导致缓冲区溢出。

你应该使用:

*a = malloc(strlen(temp) + 1);

不需要malloc()在 C 中强制转换返回值,并且sizeof (char)始终为 1。

于 2012-05-28T09:13:54.463 回答