c
复制代码
#ifndef CLIPFILE_H
#define CLIPFILE_H
#include <stdbool.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
// 将文本内容复制到剪贴板
bool clipclipfile_copy_text(const char* text);
// 将文件内容复制到剪贴板
bool clipfile_copy_file(const char* filename);
#ifdef __cplusplus
}
#endif
#endif // CLIPFILE_H
#ifdef CLIPFILE_IMPLEMENTATION
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
// 内部函数:获取文件大小
static size_t clipfile_get_file_size(const char* filename) {
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA file_info;
if (!GetFileAttributesExA(filename, GetFileExInfoStandard, &file_info)) {
return 0;
}
return (size_t)((file_info.nFileSizeHigh * (MAXDWORD + 1LL)) + file_info.nFileSizeLow);
#else
struct stat st;
if (stat(filename, &st) != 0) {
return 0;
}
return (size_t)st.st_size;
#endif
}
// 将文本内容复制到剪贴板
bool clipfile_copy_text(const char* text) {
if (!text) return false;
#ifdef _WIN32
// Windows 实现
if (!OpenClipboard(NULL)) return false;
if (!EmptyClipboard()) {
CloseClipboard();
return false;
}
size_t text_len = strlen(text);
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, text_len + 1);
if (!hMem) {
CloseClipboard();
return false;
}
char* pMem = (char*)GlobalLock(hMem);
if (pMem) {
strcpy(pMem, text);
GlobalUnlock(hMem);
SetClipboardData(CF_TEXT, hMem);
} else {
GlobalFree(hMem);
hMem = NULL;
}
CloseClipboard();
return hMem != NULL;
#else
// Unix-like 实现
const char* cmd;
#ifdef __APPLE__
cmd = "pbcopy";
#else
cmd = "xclip -selection clipboard";
#endif
FILE* pipe = popen(cmd, "w");
if (!pipe) return false;
fputs(text, pipe);
int ret = pclose(pipe);
return ret == 0;
#endif
}
// 将文件内容复制到剪贴板
bool clipfile_copy_file(const char* filename) {
if (!filename) return false;
// 获取文件大小
size_t file_size = clipfile_get_file_size(filename);
if (file_size == 0) {
// 可能是0字节文件或错误,仍尝试读取
file_size = 1024; // 初始缓冲区大小
}
// 分配缓冲区
char* buffer = (char*)malloc(file_size + 1);
if (!buffer) return false;
// 打开文件
FILE* file = fopen(filename, "rb");
if (!file) {
free(buffer);
return false;
}
// 读取文件内容
size_t bytes_read = fread(buffer, 1, file_size, file);
fclose(file);
// 处理实际读取的字节数
if (bytes_read == 0) {
free(buffer);
return false; // 空文件或读取错误
}
// 确保字符串以null结尾
buffer[bytes_read] = '\0';
// 复制到剪贴板
bool success = clipfile_copy_text(buffer);
free(buffer);
return success;
}
#endif // CLIPFILE_IMPLEMENTATION
#ifdef CLIPFILE_MAIN
#include <stdio.h>
static void print_usage(const char* prog_name) {
fprintf(stderr, "用法: %s [选项] <文件名>\n", prog_name);
fprintf(stderr, "将指定文件的内容复制到系统剪贴板\n\n");
fprintf(stderr, "选项:\n");
fprintf(stderr, " -h, --help 显示此帮助信息\n");
fprintf(stderr, " -v, --version 显示版本信息\n");
}
static void print_version(void) {
fprintf(stderr, "clipfile 1.0\n");
fprintf(stderr, "跨平台文件内容复制到剪贴板工具\n");
}
int main(int argc, char* argv[]) {
// 解析命令行参数
if (argc < 2) {
print_usage(argv[0]);
return 1;
}
const char* filename = NULL;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
print_usage(argv[0]);
return 0;
} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
print_version();
return 0;
} else if (filename == NULL) {
filename = argv[i];
} else {
fprintf(stderr, "错误: 过多的参数\n");
print_usage(argv[0]);
return 1;
}
}
if (!filename) {
fprintf(stderr, "错误: 未指定文件名\n");
print_usage(argv[0]);
return 1;
}
// 复制文件内容到剪贴板
bool success = clipfile_copy_file(filename);
if (success) {
printf("成功将文件内容复制到剪贴板: %s\n", filename);
return 0;
} else {
fprintf(stderr, "错误: 无法复制文件内容到剪贴板: %s\n", filename);
return 1;
}
}
#endif // CLIPFILE_MAIN