有没有大佬帮我看看这是怎么回事,关于sd库

2024-03-314019
AI 快速预览详细 收起
本文探讨了在使用SD库进行文件操作时遇到的一个常见问题:在递归函数中打开文件。通过分析代码示例,发现将文件打开操作放在递归函数内部可以解决问题。具体来说,在每次递归调用前重新打开文件,并在调用后关闭文件,确保文件操作的正确性。这种改进方法可以帮助开发者顺利实现从SD卡文件中用拼音查询汉字的功能。

以下是完整代码:

 

#include<SD.h>

#include<SPI.h>

#include<String.h>

unsigned long fileLength=0;//文件长度

unsigned long poipos=0;//文件指针位置

File file;

String matchPinyin(String);

String search(String,unsigned long,unsigned long);

void setup() {

  // put your setup code here, to run once:

  Serial.begin(115200);

  Serial.println(SD.begin(SPI_HALF_SPEED, 4));

  File file=SD.open("1.txt",FILE_READ);

  fileLength=file.available();

  file.close();

  Serial.println("汉字");

  Serial.println(matchPinyin("a "));

  Serial.println(matchPinyin("zuo "));

  Serial.println(matchPinyin("hao "));

  Serial.println("done");

}

String matchPinyin(String val)

{

  return search(val,0,fileLength);

}

String search(String val,unsigned long a,unsigned long b)//传递原值,首位,末位,识别位数

{

  char word=0;//缓存所取

  int sub=0;//比较下标

  File file=SD.open("1.txt",FILE_READ);

  unsigned long mid=a/2+b/2;

  Serial.print(a);

  Serial.print(",");

  Serial.print(b);

  Serial.print(":");

  Serial.println(mid);

  if((b-a)<2)

  {

    return "";

  }

  //Serial.println("front find");

  file.seek(mid);

  while(file.peek()!=10/*不是换行*/)//连续向上查询

  {

    /*Serial.print("    ");

    Serial.print(mid);

    Serial.print(" ");

    Serial.println(file.peek());*/

    mid--;

    file.seek(mid);

  }

  //Serial.println("back find");

  poipos=mid;

  while(file.peek()!=9/*不是空格*/)//连续向下查询

  {

    /*Serial.print("    ");

    Serial.print(file.peek());

    Serial.print(" ");

    Serial.println(char(file.peek()));*/

    file.seek(++poipos);

  }

  while(file.seek(++poipos),(word=file.peek())!='\r'/*不是回车*/)//依次比较

  {

    /*Serial.print("   ");

    Serial.print(char(val[sub]));

    Serial.print("==");

    Serial.print(char(word));*/

    if(val[sub]==word)

    {

      sub++;

    }

    else if(word>val[sub])//从前寻找

    {

      Serial.println("front");

      yield();

      file.close();

      return(search(val,a,(a+b)/2));

    }

    else if(word<val[sub])//从后寻找

    {

      Serial.println("back");

      yield();

      file.close();

      return(search(val,(a+b)/2,b));

    }

  }

  //此次选择正确

  String ret="";

  file.seek(++mid);

  while(file.peek()!=9)

  {

    ret+=char(file.read());

  }

  file.close();

  return ret;

}

void loop() {

  // put your main code here, to run repeatedly:

  

}

 

想做一个从SD卡里的文件用拼音查询汉字的程序,但是File file=SD.open("1.txt",FILE_READ); 这一句只能写到递归函数里,写到初始化里在递归函数里就不能操作文件了,是什么情况?怎么改进呢?

 

 

 

 

 

 

 

 

SD库文件操作问题:递归函数中打开文件的解决方案_image_1.webp

 

 

 

 

 

以下是打开的文件(部分)

 

 

 

SD库文件操作问题:递归函数中打开文件的解决方案_image_2.webp

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(2)
DFEDU
DFEDU
试试这样
#include
#include
#include
unsigned long fileLength = 0; //文件长度
unsigned long poipos = 0; //文件指针位置
File file;
String matchPinyin(String);
String search(String, unsigned long, unsigned long, File &);
void setup()
{
Serial.begin(115200);
Serial.println(SD.begin(SPI_HALF_SPEED, 4));
file = SD.open("1.txt", FILE_READ);
fileLength = file.available();
file.close();
Serial.println("汉字");
Serial.println(matchPinyin("a "));
Serial.println(matchPinyin("zuo "));
Serial.println(matchPinyin("hao "));
Serial.println("done");
}
String matchPinyin(String val)
{
file = SD.open("1.txt", FILE_READ);
return search(val, 0, fileLength, file);
}
String search(String val, unsigned long a, unsigned long b, File &file)
{
char word = 0; //缓存所取
int sub = 0; //比较下标
unsigned long mid = a / 2 + b / 2;
Serial.print(a);
Serial.print(",");
Serial.print(b);
Serial.print(":");
Serial.println(mid);
if ((b - a) < 2)
{
return "";
}
file.seek(mid);
while (file.peek() != 10)
{
mid--;
file.seek(mid);
}
poipos = mid;
while (file.peek() != 9)
{
file.seek(++poipos);
}
while ((file.seek(++poipos), (word = file.peek())) != '\r')
{
if (val[sub] == word)
{
sub++;
}
else if (word > val[sub])
{
Serial.println("front");
yield();
file.close();
return (search(val, a, (a + b) / 2, file));
}
else if (word < val[sub])
{
Serial.println("back");
yield();
file.close();
return (search(val, (a + b) / 2, b, file));
}
}
String ret = "";
file.seek(++mid);
while (file.peek() != 9)
{
ret += char(file.read());
}
return ret;
}
void loop()
{
}
开在边缘
开在边缘回复operator
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println(SD.begin(SPI_HALF_SPEED, 4));
File file=SD.open("1.txt",FILE_READ);
String search(String val,unsigned long a,unsigned long b)//传递原值,首位,末位,识别位数
{
char word=0;//缓存所取
int sub=0;//比较下标
File file=SD.open("1.txt",FILE_READ);
因为你在函数里面又重新定义了一次file,所以函数里面的file就变成了函数内部的局部变量,不再是你之前定义的那个全局变量了。
operator
operator
作者
回复DFEDU
问题解决了,谢谢!但是file是全局变量,为什么在初始化里赋值不可以?
operator
operator
作者
补两张图片


- 没有更多了 -