我正在使用一些带有嵌入式设备的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 * 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。我想我应该发布更新以防万一有任何想法,但我的假设是这与文件名字符串有关。
答案 0 :(得分:1)
您的代码可能有几个问题:
1)您可能正在传递“隐形”字符,例如空格。请确保您传递的字符串完全相同,即按字符打印字符,包括空终止,并查看它们是否相同。
2)API和其他API使用的后者返回的值可能不符合预期。我建议你(如果可能的话)看一下API源代码。如果您可以编译API本身,那么应该很容易找到问题(检查API getFileSize()从参数获取的内容)。根据您发送的API文档,在获得-1之后检查存储在buffer[DOS_BUFFER_SIZE]
中的值。
编辑(查看API源代码后):
在线 00657 (func find_file_in_dir
),你有:
if(strcmp(dir_entry-&gt; long_name,name)== 0)
这似乎是使用字符串文字而不是从函数中获取名称时会有不同答复的唯一原因。所以你很可能没有传递相同的值(即你要么传递隐形字符,要么你没有传递字符串终止)。
最后注意:在每个代码之前检查缓冲区[DOS_BUFFER_SIZE]的内容到SD API。
我希望这会有所帮助。
亲切的问候,
博
答案 1 :(得分:0)
此:
if(strstr(temp, ".jpg") && !strstr(temp, "_")) {
*a = (char*)malloc(sizeof(char) * strlen(temp));
strcpy(*a, temp);
}
坏了,它没有为终结器分配空间,导致缓冲区溢出。
您应该使用:
*a = malloc(strlen(temp) + 1);
无需在C中转换malloc()
的返回值,sizeof (char)
始终为1。