山西网站制作公司哪家好,记事本做网站报告,徐州建设工程网上交易平台,网站开发分层当您使用 C 编程语言时#xff0c;您可能会遇到一些需要将文件读入字符数组的问题#xff0c;例如分析每个字符的频率#xff0c;或者将所有句子的每个起始词从小写转换为大写#xff0c;反之亦然。该解决方案非常简单#xff0c;但对于不太了解文件读取或写入的人来说可能…当您使用 C 编程语言时您可能会遇到一些需要将文件读入字符数组的问题例如分析每个字符的频率或者将所有句子的每个起始词从小写转换为大写反之亦然。该解决方案非常简单但对于不太了解文件读取或写入的人来说可能并不那么简单。因此在这篇文章中您可以逐步学习如何在 C 中将文件读入字符数组。
在 C 中打开文件
在 C 语言中打开文件的最简单和最流行的方法是使用以下格式的“fopen”函数
file fopen(file_name, open_mode); //open the file-name file and store the file pointer in the variable file
“fopen”函数的模式参数指定打开文件的模式。该模式可以是以下之一
“ r ”打开文件进行读取。“ w ”将文件截断为零长度或创建一个用于写入的文件。“ a ”追加到文件或创建一个文件如果不存在进行写入。“ r ”打开文件进行读写。“ w ”将文件截断为零长度或创建一个用于读写的文件。“ a ”追加到文件或创建文件以供读写。
但由于某种原因该文件可能无法正常打开。为了在发生此类情况时做好准备您应该始终检查“fopen”函数的返回值以确保在尝试读取或写入文件之前已成功打开文件。像这样
// If fopen returns NULL, print an error message and exit the program
if (file NULL) {printf(Error: Failed to open file %s.\n, file_name);return 1;
}
逐字符读取文件内容
在读取文件之前您必须有一个字符数组来存储文件内容。让我们这样做吧
char buffer[1000]; //Initialize a char array named buffer with size of 1000
现在是时候使用“fgetc”读取文件了。该函数每次调用都会读取文件中的一个字符如果重复调用它将读取后续的每个字符直到结束。因此我们可以使用 while 循环来使过程变得更容易。
int i 0, c; //c is the intermediate variable, i is the increment variable
while ((c fgetc(file)) ! EOF) {//Read contents until it reach the end of the filebuffer[i] c;i;
}
上面的示例假设文件仅包含 ASCII 字符并且文件大小小于 1000 个字符。
可调整大小的缓冲区
我们之前定义的缓冲区数组最多包含 1000 个字符。但在许多情况下文件大小远大于此。我们可以通过将缓冲区变成可调整大小的缓冲区来解决这个问题。您可以通过 C 标准库提供的“malloc”、“realloc”和“realloc”函数使用动态内存分配。
char *buffer NULL; // initialize buffer to NULL
int buffer_size 0;
/*Open the file here*/
// Read file character by character
int c, i 0;
while ((c fgetc(file)) ! EOF) {// If buffer is full, resize itif (i buffer_size) {buffer_size 1000; // increase buffer size by 1000 bytesbuffer realloc(buffer, buffer_size); // resize bufferif (buffer NULL) {printf(Error: Memory allocation failed.\n);return 1;}}buffer[i] c;i;
}
我们在上面的代码片段中使用“realloc”函数这被证明是有用的因为文件大小通常是事先未知的。对于“malloc”和“calloc”函数它们可用于将指定大小的内存块分配给变量。在此示例中您可以像下面这样使用
buffer (char*)malloc(1000); //is the same as define char buffer[1000]
在此示例中您可能不需要使用“malloc”和“calloc”。我们稍后会再次见到他们。
文件包含非 ASCII 字符
在 C 中字符串表示为字节序列这些字节的解释取决于字符编码。如果文件包含非 ASCII 字符则需要使用支持这些字符的字符编码例如 UTF-8 或 UTF-16。
对于这个问题您应该使用可以处理多字节字符的函数例如“fgetwc”和“fgetws”。这些函数一次分别读取一个宽字符 (wchar_t) 或一个宽字符串 (wchar_t*)。
以下是对代码的一些修改以使其在文件包含非 ASCII 字符时正常工作
wchar_t buffer[100];
// Open file for reading
file fopen(filename, r,ccsUTF-8);
// Read file contents
wchar_t c;
int i 0;
while ((c fgetwc(file)) ! WEOF) {buffer[i] c;i;
}
另外请确保输入和输出流设置为正确的编码以正确显示或操作字符。在 MacOS 和 Linux 等 Unix 操作系统上为了确保输出编码为 UTF-8您可以使用 setlocale 函数
#include
int main()
{setlocale(LC_ALL, en_US.utf8);// your code herereturn 0;
}
在 Windows 上您可以使用 _setmode 和 _O_U8TEXT 函数将输出编码设置为 UTF-8
#include //_O_U8TEXT
#include //_setmode()
int main()
{_setmode(_fileno(stdout), _O_U8TEXT);// your code herereturn 0;
}
以下是包含越南语单词“Xin chào!”的文件示例 (Hello) 带重音符号非 ASCII 字符以 UTF-8 编码保存
Xin chào!
这是我们的程序在在线 C 编译器上运行后的输出
Xin chào!...Program finished with exit code 0
Press ENTER to exit console.
读取整个文件内容
如果您不熟悉 C那么您可以跳过此步骤但我仍然建议将其作为高级练习来阅读。我想介绍另一种方法来解决“如何在 C 中将文件读入字符数组”问题。新的思路是不再逐个字符地读取文件而是整体读取文件在读取之前确定文件大小。这是一个更复杂的解决方案但也更有效。
首先您应该定义常用变量用于打开文件的文件指针和用于包含字符数组的缓冲区。请记住您还需要文件大小
FILE *fp;
long file_size;
char *buffer;
然后就可以打开文件来读取
fp fopen(example.txt, r);要了解文件的大小可以使用“ftell”函数。它将告诉文件指针中当前位置的字节位置current_byte ftell(fp);
但是等等文件读取总是从文件的开头开始。没问题“fseek”函数会将读取控件移动到文件中的不同位置
fseek(fp, 0, SEEK_END);
您现在可以正确获取文件大小。之后我们再次将读取控件设置为开头开始读取文件内容
file_size ftell(fp);
rewind(fp); move the control to the files beginning// Allocate memory for the char array
buffer (char*) malloc(file_size 1);
这里“malloc”函数的使用非常简单分配内存来创建一个未初始化的 char 数组其大小为 (file_size1) 乘以 1 字节char 类型的大小。
如果您想使用“calloc”函数请按以下步骤操作
buffer (char*) calloc(file_size 1, sizeof(char));
“malloc”和“calloc”之间的主要区别在于“malloc”仅分配内存而不初始化其内容而“calloc”既分配内存又将内存初始化为零。使用“calloc”的主要优点是分配的内存已经被清零如果您打算稍后将 char 数组用作字符串这会很有帮助。
// Read the file into the char array
fread(buffer, file_size, 1, fp);
创建缓冲区后您可以使用“fread”函数读取整个文件该函数获取文件指针、要读取的每个元素的大小、要读取的元素的数量以及目标数组。
// Add a null terminator at the end of the char array
buffer[file_size] \0;
您可能想知道为什么需要为“缓冲区”分配额外的字节。为什么不只是file_size而是file_size 1在这里将在 char 数组的末尾添加 null 终止符以指示字符串的结束。实际上如果您唯一的任务是将文件读入数组那么这一步是不必要的。但稍后如果您想将此数组打印为字符串那么这是一个要求。C 中的字符串被定义为将最后一个字符作为空终止符“\0”。
清理你的代码
您已经打开并使用了该文件因此请记住随后将其关闭。只需使用“fclose”函数来释放您分配的“文件”指针变量。
fclose(file);
谈到释放指针还记得用来存储字符的“缓冲区”数组吗如果您将其定义为已分配的内存指针那么最好立即释放它以避免内存泄漏。
free(buffer);
以下是您的解决方案的概述
#include
#include int main() {FILE *file;char filename[] example.txt;char *buffer NULL; // initialize buffer to NULLint buffer_size 0;int i 0;//Open file for readingfile fopen(filename, r);//Check if file opened successfullyif (file NULL) {printf(Error: Failed to open file %s.\n, filename);return 1;}// Read file character by characterint c;while ((c fgetc(file)) ! EOF) {// If buffer is full, resize itif (i buffer_size) {buffer_size 1000; // increase buffer size by 1000 bytesbuffer realloc(buffer, buffer_size); // resize bufferif (buffer NULL) {printf(Error: Memory allocation failed.\n);return 1;}}buffer[i] c;i;}// Close filefclose(file);// Print the character arrayprintf(%s, buffer);// Free the dynamically allocated bufferfree(buffer);return 0;
}