我想打开一个文件,读取其内容并使用C代码存储在数组中。
我在Windows笔记本电脑上做到了,但是当我在RaspberryPi上尝试代码时,我会得到分割错误。我已经尝试了一段时间来debugm,我是C的新手,所以我很难找到自己做错了什么。
char *readFile(char *fileName)
{
FILE *ptr_file;
char *ptr_data;
int n = 0;
char c;
ptr_file = fopen(fileName, "r");
if(ptr_file == NULL)
{
perror("File could not be opened.n");
exit(EXIT_FAILURE);
}
fseek(ptr_file, 0, SEEK_END);
long f_size = ftell(ptr_file);
fseek(ptr_file,0, SEEK_SET);
ptr_data = (char *)malloc(f_size+1);
if(ptr_data == NULL)
{
perror("MALLOC FAILED");
exit(EXIT_FAILURE);
}
while((c = fgetc(ptr_file)) != EOF)
{
ptr_data[n++] = (char)c;
}
ptr_data[n] = ' ';
fclose(ptr_file);
return ptr_data;
}
对我来说,段错误似乎出现在致电malloc
之后的while循环中。
为什么它可以在我的笔记本电脑上工作而不是在Raspberrypi上?
同时,我不明白为什么ID执行此操作,我为什么会在RPI上遇到细分错误:
int main(int argc, char *argv[])
{
char data[100] = {};
FILE *ptr_file;
char *ptr_data=data;
int n = 0, i = 0;
char c;
ptr_file = fopen(fileName, "r");
if(ptr_file == NULL)
{
perror("File could not be opened.n");
exit(EXIT_FAILURE);
}
while((c = fgetc(ptr_file)) != EOF)
{
ptr_data[n++] = (char)c;
}
ptr_data[n] = ' ';
while(i <n,i++)
{
printf("%cn",data[i]);
fclose(ptr_file);
}
返回0;}
在不同环境上读取文本文件时,存在一些问题。例如,在编写新行时,可以在Windows上消耗2个字节,而Linux上只需1个字节。从文章中:
c标准的第7.21.9.4节[ISO/IEC 9899:2011]指定 在文本模式下打开文本文件时,ftell()的以下行为:
For a text stream, its file position indicator contains unspecified information, usable by the fseek function for returning the file position indicator for the stream to its position at the time of the ftell call.
因此,流的ftell()返回值 在文本模式下打开,绝不应用于偏移计算其他 而不是打电话给fseek()。
另外,FSEEK和FTELL功能行为可能会有所不同,具体取决于您正在使用的环境。
有关进一步的解释,您可以阅读此主题:https://www.securecoding.cert.org/confluence/display/seccode/seccode/fio14-c. dunderstand the deffere difference teext text text mmode mmode and binary binary mmode mode mode file file file 斯特雷姆斯
也许您应该禁用Linux内存过度使用。看到这个。
顺便说一句,您可以考虑使用Open(2)打开文件,FSTAT(2)以获取统计信息,尤其是文件大小,然后MMAP(2)通过增加地址空间来将文件投影到虚拟内存中。
int fd = open(fileName, O_RDONLY);
if (fd<0) { perror(fileName); exit(EXIT_FAILURE); };
struct stat fs;
memset (&fs, 0, sizeof(fs));
if (fstat(fd, &fs)) { perror("fstat"); exit(EXIT_FAILURE); };
long pgsz = sysconf(_SC_PAGE_SIZE); // a power of two
size_t roundedsz = (fs.st_size | (pgsz-1)) + 1; // round up the size
void* ad = mmap(NULL, roundedsz, PROT_READ, MAP_SHARED, fd, (off_t)0);
if (ad == MMAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); };
然后使用ad
代替ptr_data
(这变得无用)。完成后,不要忘记致电munmap
和close
...
如果愿意,您可以在mmap
之后close
。
阅读高级Linux编程。