C语言怎么读写文件 一、C语言创建文件 1. 使用C语言创建一个文本文件log.txt并写入hello,world 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <stdio.h> int main () { FILE *file; file = fopen("log.txt" , "w" ); if (file == NULL ) { printf ("无法创建文件。\n" ); return 1 ; } fprintf (file, "hello,world\n" ); fclose(file); printf ("文件创建并写入成功!\n" ); return 0 ; }
2. 使用C语言打开log.txt并在下一行添加字符串”你好,世界” 将打开模式修改为 "a"(追加模式):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <stdio.h> int main () { FILE *file; file = fopen("log.txt" , "a" ); if (file == NULL ) { printf ("无法创建文件。\n" ); return 1 ; } fprintf (file, "hello,world\n" ); fclose(file); return 0 ; }
二、C语言读取文件 1. 用C语言读取第一行的字符串并打印。 要用 C 语言读取文本文件的第一行字符串并打印出来,可以按照以下步骤进行:
打开文件 :使用 fopen 函数以读取模式打开目标文件。
读取第一行 :使用 fgets 函数从文件中读取一行字符串。
打印字符串 :将读取的字符串输出到控制台。
关闭文件 :使用 fclose 函数关闭文件,释放资源。
下面是完整的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h> int main () { FILE *file; char buffer[1024 ]; file = fopen("log.txt" , "r" ); if (file == NULL ) { printf ("无法打开文件。\n" ); return 1 ; } if (fgets(buffer, sizeof (buffer), file) != NULL ) { printf ("文件的第一行内容是:%s" , buffer); } else { printf ("文件是空的或读取错误。\n" ); } fclose(file); return 0 ; }
2. 用C语言读取每一行的字符串并打印。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <stdio.h> int main () { FILE *file; char buffer[256 ]; file = fopen("log.txt" , "r" ); if (file == NULL ) { printf ("无法打开文件。\n" ); return 1 ; } while (fgets(buffer, sizeof (buffer), file) != NULL ) { printf ("%s" , buffer); } fclose(file); return 0 ; }
3. C语言以二进制的方式读取第一行字符串并以16进制打印。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <stdio.h> #include <stdlib.h> int main () { FILE *file; unsigned char buffer[1024 ]; size_t bytesRead = 0 ; int ch; file = fopen("log.txt" , "rb" ); if (file == NULL ) { printf ("无法打开文件。\n" ); return 1 ; } while (bytesRead < sizeof (buffer)) { ch = fgetc(file); if (ch == EOF) { break ; } buffer[bytesRead++] = (unsigned char )ch; if (ch == '\n' || ch == '\r' ) { if (ch == '\r' ) { int next_ch = fgetc(file); if (next_ch == '\n' ) { buffer[bytesRead++] = (unsigned char )next_ch; } else if (next_ch != EOF) { ungetc(next_ch, file); } } break ; } } fclose(file); if (bytesRead > 0 ) { printf ("第一行的十六进制内容是:\n" ); for (size_t i = 0 ; i < bytesRead; i++) { printf ("%02X " , buffer[i]); } printf ("\n" ); } else { printf ("文件是空的或读取错误。\n" ); } return 0 ; }
4. C语言以二进制的方式读取log.txt,并将结果以16进制写入到文本中。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <stdio.h> #include <stdlib.h> int main () { FILE *inputFile, *outputFile; unsigned char buffer[1024 ]; size_t bytesRead; inputFile = fopen("log.txt" , "rb" ); if (inputFile == NULL ) { printf ("无法打开输入文件。\n" ); return 1 ; } outputFile = fopen("output.txt" , "w" ); if (outputFile == NULL ) { printf ("无法创建输出文件。\n" ); fclose(inputFile); return 1 ; } while ((bytesRead = fread(buffer, 1 , sizeof (buffer), inputFile)) > 0 ) { for (size_t i = 0 ; i < bytesRead; i++) { fprintf (outputFile, "%02X " , buffer[i]); } fprintf (outputFile, "\n" ); } fclose(inputFile); fclose(outputFile); printf ("文件内容已成功以十六进制格式写入到 output.txt。\n" ); return 0 ; }
三、C语言删除文件
要使用 C 语言删除一个文件(例如 log.txt),可以使用标准库函数 remove。这个函数用于删除指定路径的文件,如果删除成功,返回 0,否则返回一个非零值。
以下是一个完整的代码示例,展示了如何删除文件 log.txt:
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> int main () { if (remove("log.txt" ) == 0 ) { printf ("文件 log.txt 已成功删除。\n" ); } else { perror("删除文件 log.txt 失败" ); } return 0 ; }
注意事项 :
文件路径 :确保提供的文件路径正确,如果文件不在当前目录下,需要提供完整路径,例如 remove("/path/to/log.txt")。
文件权限 :确保程序有权限删除指定的文件,否则 remove 函数会失败。
检查文件是否存在 :删除之前,可以检查文件是否存在,避免不必要的错误处理。
四、C语言复制文件 复制文件log.txt到其他路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <stdio.h> int copyFile (const char *sourcePath, const char *destPath) { FILE *sourceFile, *destFile; unsigned char buffer[1024 ]; size_t bytesRead; sourceFile = fopen(sourcePath, "rb" ); if (sourceFile == NULL ) { printf ("无法打开源文件 %s。\n" , sourcePath); return 1 ; } destFile = fopen(destPath, "wb" ); if (destFile == NULL ) { printf ("无法创建目标文件 %s。\n" , destPath); fclose(sourceFile); return 1 ; } while ((bytesRead = fread(buffer, 1 , sizeof (buffer), sourceFile)) > 0 ) { fwrite(buffer, 1 , bytesRead, destFile); } fclose(sourceFile); fclose(destFile); printf ("文件已成功从 %s 复制到 %s。\n" , sourcePath, destPath); return 0 ; } int main () { const char *sourcePath = "log.txt" ; const char *destPath = "/home/kali/cc++/log.txt" ; int result = copyFile(sourcePath, destPath); return result; }
以二进制读取的任何文件都能复制。
五、C语言修改文件 1. 用C语言修改第一行的字符串为abcdefg 方法:使用临时文件,适合处理大文件
如果文件很大,读取整个文件到内存可能不太现实。可以采取以下方法:
同时打开原文件和临时文件:
逐行读取原文件,写入临时文件:
读取第一行,写入修改后的内容 abcdefg 到临时文件。
从第二行开始,直接将读取的内容写入临时文件,不做修改。
替换原文件:
关闭文件后,删除原文件。
将临时文件重命名为原文件名。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE_LENGTH 1024 int main () { FILE *file_in, *file_out; char buffer[MAX_LINE_LENGTH]; int line_number = 0 ; file_in = fopen("log.txt" , "r" ); if (file_in == NULL ) { printf ("无法打开原文件。\n" ); return 1 ; } file_out = fopen("temp_log.txt" , "w" ); if (file_out == NULL ) { printf ("无法创建临时文件。\n" ); fclose(file_in); return 1 ; } while (fgets(buffer, MAX_LINE_LENGTH, file_in) != NULL ) { line_number++; if (line_number == 1 ) { fprintf (file_out, "abcdefg\n" ); } else { fputs (buffer, file_out); } } if (line_number == 0 ) { fprintf (file_out, "abcdefg\n" ); } fclose(file_in); fclose(file_out); if (remove("log.txt" ) != 0 ) { printf ("无法删除原文件。\n" ); return 1 ; } if (rename("temp_log.txt" , "log.txt" ) != 0 ) { printf ("无法重命名临时文件。\n" ); return 1 ; } printf ("文件的第一行已成功修改为 'abcdefg'。\n" ); return 0 ; }
方法详解:
文件操作:
file_in:指向原始文件,用于读取。
file_out:指向临时文件,用于写入。
流程说明:
读取和写入:
使用 fgets 从原文件读取每一行。
使用 fprintf 或 fputs 将内容写入临时文件。
对第一行进行特殊处理,替换为 abcdefg。
文件替换:
关闭所有文件指针后,使用 remove 删除原文件。
使用 rename 将临时文件重命名为原文件名,实现文件的替换。
优点:
高效性: 无需将整个文件内容加载到内存中,适合处理大型文件。
简洁性: 代码逻辑清晰,易于理解和维护。
注意事项:
错误处理: 在删除和重命名文件时,必须检查返回值,确保文件操作成功。
权限问题: 程序需要有删除和修改文件的权限。
2. 以二进制的方式将第二行中的’abcdefg’修改为’hijklmn’ 要用 C 语言以二进制方式读取文件,并将第二行中的 ‘abcdefg’ 修改为 ‘hijklmn’,需要以下步骤:
打开文件:以二进制读写模式打开文件。
读取文件内容:逐行读取文件,找到第二行并进行修改。
写回修改后的内容:将修改后的内容重新写回文件。
以下是一个完整的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFER_SIZE 1024 int main () { FILE *file; char buffer[BUFFER_SIZE]; long secondLinePos = 0 ; int currentLine = 0 ; file = fopen("log.txt" , "rb+" ); if (file == NULL ) { perror("无法打开文件" ); return 1 ; } while (fgets(buffer, sizeof (buffer), file) != NULL ) { currentLine++; if (currentLine == 2 ) { secondLinePos = ftell(file) - strlen (buffer); break ; } } if (currentLine < 2 ) { printf ("文件没有第二行。\n" ); fclose(file); return 1 ; } fseek(file, secondLinePos, SEEK_SET); if (fgets(buffer, sizeof (buffer), file) != NULL ) { char *pos = strstr (buffer, "abcdefg" ); if (pos != NULL ) { fseek(file, secondLinePos + (pos - buffer), SEEK_SET); fwrite("hijklmn" , sizeof (char ), strlen ("hijklmn" ), file); } } fclose(file); printf ("第二行中的 'abcdefg' 已修改为 'hijklmn'。\n" ); return 0 ; }
代码解析:
包含头文件:
#include <stdio.h>:标准输入输出库,提供文件操作。
#include <stdlib.h>:标准库。
#include <string.h>:字符串处理库。
宏定义:
#define BUFFER_SIZE 1024:定义缓冲区大小。
主程序:
FILE *file;:文件指针。
char buffer[BUFFER_SIZE];:缓冲区,用于存储读取的行。
long secondLinePos = 0;:用于存储第二行的文件位置。
int currentLine = 0;:用于记录当前行号。
打开文件:
使用 fopen("log.txt", "rb+") 以二进制读写模式打开文件。
读取文件并寻找第二行的位置:
使用 fgets 逐行读取文件内容。
当前行号递增,如果达到第二行,记录当前文件位置。
修改第二行的内容:
使用 fseek 移动文件指针到第二行的位置。
使用 strstr 查找 ‘abcdefg’ 的位置。
使用 fwrite 写入 ‘hijklmn’,覆盖原有内容。
关闭文件:
注意事项:
文件路径:确保文件路径正确,并且文件存在。
文件权限:确保程序有权限读取和修改文件。
字符串匹配:代码假设 ‘abcdefg’ 在第二行中出现,且长度相同。否则需要更复杂的处理。
3. 以二进制的方式将第二行中的’abcdefg’修改为’hijklmn’,逐个写入字符的 ASCII 码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFER_SIZE 1024 int main () { FILE *file; char buffer[BUFFER_SIZE]; long secondLinePos = 0 ; int currentLine = 0 ; file = fopen("log.txt" , "rb+" ); if (file == NULL ) { perror("无法打开文件" ); return 1 ; } while (fgets(buffer, sizeof (buffer), file) != NULL ) { currentLine++; if (currentLine == 2 ) { secondLinePos = ftell(file) - strlen (buffer); break ; } } if (currentLine < 2 ) { printf ("文件没有第二行。\n" ); fclose(file); return 1 ; } fseek(file, secondLinePos, SEEK_SET); if (fgets(buffer, sizeof (buffer), file) != NULL ) { char *pos = strstr (buffer, "abcdefg" ); if (pos != NULL ) { fseek(file, secondLinePos + (pos - buffer), SEEK_SET); const char *newStr = "hijklmn" ; for (size_t i = 0 ; i < strlen (newStr); i++) { fputc(newStr[i], file); } } } fclose(file); printf ("第二行中的 'abcdefg' 已修改为 'hijklmn'。\n" ); return 0 ; }
六、C语言调用Linux系统函数复制文件夹 1. 复制文件夹的步骤:
打开源文件夹。
创建目标文件夹。
遍历源文件夹中的每个条目:
如果是文件,复制文件。
如果是子文件夹,递归复制子文件夹。
处理错误和边界情况(例如文件权限问题)。
2. 代码示例: 以下是一个实现上述步骤的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <unistd.h> #define BUFFER_SIZE 1024 int copyFile (const char *sourcePath, const char *destPath) { FILE *sourceFile, *destFile; char buffer[BUFFER_SIZE]; size_t bytesRead; sourceFile = fopen(sourcePath, "rb" ); if (sourceFile == NULL ) { perror("无法打开源文件" ); return 1 ; } destFile = fopen(destPath, "wb" ); if (destFile == NULL ) { perror("无法创建目标文件" ); fclose(sourceFile); return 1 ; } while ((bytesRead = fread(buffer, 1 , sizeof (buffer), sourceFile)) > 0 ) { fwrite(buffer, 1 , bytesRead, destFile); } fclose(sourceFile); fclose(destFile); return 0 ; } int copyDirectory (const char *sourceDir, const char *destDir) { DIR *dir; struct dirent *entry ; struct stat statBuffer ; mkdir(destDir, 0755 ); dir = opendir(sourceDir); if (dir == NULL ) { perror("无法打开源文件夹" ); return 1 ; } while ((entry = readdir(dir)) != NULL ) { char sourcePath[PATH_MAX]; char destPath[PATH_MAX]; if (strcmp (entry->d_name, "." ) == 0 || strcmp (entry->d_name, ".." ) == 0 ) { continue ; } snprintf (sourcePath, sizeof (sourcePath), "%s/%s" , sourceDir, entry->d_name); snprintf (destPath, sizeof (destPath), "%s/%s" , destDir, entry->d_name); if (stat(sourcePath, &statBuffer) == -1 ) { perror("无法获取文件属性" ); continue ; } if (S_ISDIR(statBuffer.st_mode)) { copyDirectory(sourcePath, destPath); } else { copyFile(sourcePath, destPath); } } closedir(dir); return 0 ; } int main () { const char *sourceDir = "/home/kali/cc++/crawler" ; const char *destDir = "/home/kali/cc++/crawler_copy" ; if (copyDirectory(sourceDir, destDir) == 0 ) { printf ("文件夹复制成功!\n" ); } else { printf ("文件夹复制失败!\n" ); } return 0 ; }
3. 代码解析:
包含头文件:
#include <stdio.h>:标准输入输出库。
#include <stdlib.h>:标准库。
#include <string.h>:字符串处理。
#include <sys/types.h> 和 #include <sys/stat.h>:文件属性操作。
#include <dirent.h>:目录操作。
#include <unistd.h>:POSIX 标准库函数。
copyFile 函数:用于复制单个文件。
打开源文件和目标文件。
逐块读取源文件并写入目标文件。
关闭文件。
copyDirectory 函数:用于递归复制文件夹。
使用 mkdir 创建目标文件夹。
打开源文件夹,使用 opendir 和 readdir 遍历文件夹内容。
忽略 . 和 .. 条目。
使用 stat 获取文件/文件夹属性。
如果是文件夹,递归调用 copyDirectory。
如果是文件,调用 copyFile 复制文件。
关闭目录。
main 函数:定义源文件夹和目标文件夹路径,调用 copyDirectory 函数执行复制操作。
注意事项:
路径处*:确保源文件夹和目标文件夹路径正确。
文件权限:程序需要有权限访问源文件夹和写入目标文件夹。
递归深度:确保递归深度不超过系统限制。
七、C语言调用Linux系统标准库删除文件夹 1. 删除空文件夹 以下是一个使用 rmdir 函数删除空文件夹的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> #include <unistd.h> int main () { const char *folderPath = "path/to/empty/folder" ; if (rmdir(folderPath) == 0 ) { printf ("文件夹已成功删除:%s\n" , folderPath); } else { perror("删除文件夹失败" ); } return 0 ; }
2. 递归删除非空文件夹 对于非空文件夹,可以使用 nftw 函数递归删除文件夹及其内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <stdio.h> #include <stdlib.h> #include <ftw.h> #include <unistd.h> #include <limits.h> #ifndef FTW_DEPTH #define FTW_DEPTH 8 #endif #ifndef FTW_PHYS #define FTW_PHYS 1 #endif int removeEntry (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { int ret = remove(fpath); if (ret) perror(fpath); return ret; } int removeDirectory (const char *path) { return nftw(path, removeEntry, 64 , FTW_DEPTH | FTW_PHYS); } int main () { const char *folderPath = "/home/kali/cc++/crawler_copy" ; if (removeDirectory(folderPath) == 0 ) { printf ("文件夹及其内容已成功删除:%s\n" , folderPath); } else { perror("删除文件夹失败" ); } return 0 ; }
代码解析:
删除空文件夹:
#include <unistd.h>:包含 Unix 标准库,用于系统调用。
rmdir(folderPath):尝试删除指定路径的空文件夹。
递归删除非空文件夹:
#include <ftw.h>:包含文件树遍历库。
nftw(path, removeEntry, 64, FTW_DEPTH | FTW_PHYS):递归遍历并删除目录及其内容。
removeEntry:删除单个文件或目录的回调函数。
FTW_DEPTH:深度优先遍历。
FTW_PHYS:不跟随符号链接。
注意事项:
路径处*:确保提供正确的文件夹路径,并具有删除权限。
删除非空目录:使用 rmdir 只能删除空目录,删除非空目录需要使用递归方法。
谨慎操作:递归删除目录时要小心,以防误删除重要文件夹。