c - C 中的 snprintf() 将奇怪的符号发送到 char 数组中
问题描述
我即将完成一个项目,该项目包括读取 .txt 文件并从中获取信息以将其写入另一个 .txt。到目前为止,我已经设法使用 read() 来获取信息,但是当我写入新的 .txt 时,出现了一些奇怪的情况:
List of packages
----------------
- Package Name : linux-api-headers
- Install date : 2019-03-22 21:24ÿÐüe2019-06-18 12:25
- Last update date : 2019-06-18 12:25
- How many updates : 2
- Removal date : -
- Package Name : tzdata
- Install date : 2019-03-22 21:24ÿÐüe2019-09-17 12:39
- Last update date : 2019-09-17 12:39
- How many updates : 3
- Removal date : -
我读到的输入是这样的:
[2019-03-22 21:21] [PACMAN] Running 'pacman -r /mnt -Sy --cachedir=/mnt/var/cache/pacman/pkg --noconfirm base'
[2019-03-22 21:21] [PACMAN] synchronizing package lists
[2019-03-22 21:24] [ALPM] transaction started
[2019-03-22 21:24] [ALPM] installed linux-api-headers (4.17.11-1)
[2019-03-22 21:24] [ALPM] installed tzdata (2018i-1)
[2019-03-22 21:24] [ALPM] installed iana-etc (20190228-1)
[2019-03-22 21:24] [ALPM] installed filesystem (2018.12-2)
[2019-03-22 21:24] [ALPM] installed glibc (2.28-5)
[2019-03-22 21:24] [ALPM] installed gcc-libs (8.2.1+20181127-1)
[2019-03-22 21:24] [ALPM] installed ncurses (6.1-6)
我的程序旨在查找关键字“已安装”、“升级”和“已删除”,并将其发生的日期和程序名称分开,它看起来像这样(抱歉,如果它看起来很乱):
void analyzeLog(char *logFile, char *report) {
printf("Generating Report from: [%s] log file\n", logFile);
char *file;
int fd, i;
int characters;
char buffer[1], line[1024];
int p;
int upgraded, removed, installed;
i = upgraded = removed = installed = 0;
file = logFile;
fd = open(file, O_RDONLY, 0600);
//printf("%d\n\n\n\n", fd);
if(fd == -1){
//perror("open");
printf("Unreadable");
exit(1);
}
characters = read(fd, buffer, 1);
for(;;)
{
characters = read(fd, buffer, 1);
if(characters == -1){
printf("Error");
exit(1);
break;
}
else if(characters == 0) break;
if(buffer[0] != '\n'){
line[i] = buffer[0];
i++;
}
else{
line[i++] = '\n';
line[i] = '\0';
i=0;
int j=0;
char *result;
//printf("problema\n");
if((result = strstr(line, "installed")) != NULL) {
//printf("instalacion\n");
char *doi, *position = strstr(result, " ")+1;
char nameOfProgram[64];
char dateOfInstall[20];
/*
printf("%c", position[0]);
printf("%c", position[1]);
printf("%c", position[2]);
printf("%c", position[3]);
printf("%c", position[4]);
*/
while(position[j] != ' '){
nameOfProgram[j] = position[j];
j++;
}
nameOfProgram[j] = '\0';
j=0;
//printf("%s\n", nameOfProgram);
while(files[j].name[0] != '\0'){
if(strcmp(files[j].name, nameOfProgram) == 0) {
j = -1;
break;
}
j++;
}
if(j >= 0){
strcpy(files[j].name, nameOfProgram);
//printf("%s\n", files[j].name);
doi = strstr(line, "[")+1;
int k=0;
while(doi[k] != ']'){
dateOfInstall[k] = doi[k];
k++;
}
strcpy(files[j].installDate, dateOfInstall);
}
//printf("\n%s\n", position);
installed++;
//free(result);
}
else if((result = strstr(line, "removed")) != NULL) {
//printf("removido\n");
char *dor, *position = strstr(result, " ")+1;
char nameOfProgram[64];
char dateOfRemove[20];
while(position[j] != ' '){
nameOfProgram[j] = position[j];
j++;
}
nameOfProgram[j] = '\0';
j=0;
int comparison;
while(files[j].name[0] != '\0'){
if((comparison = strcmp(files[j].name, nameOfProgram)) == 0) {
break;
}
j++;
}
if(comparison == 0){
dor = strstr(line, "[")+1;
int k=0;
while(dor[k] != ']'){
dateOfRemove[k] = dor[k];
k++;
}
strcpy(files[j].removeDate, dateOfRemove);
}
removed++;
//free(result);
}
else if((result = strstr(line, "upgraded")) != NULL) {
//printf("actualizado");
char *dou, *position = strstr(result, " ")+1;
char nameOfProgram[64];
char dateOfUpgrade[20];
while(position[j] != ' '){
nameOfProgram[j] = position[j];
j++;
}
nameOfProgram[j] = '\0';
j=0;
int comparison;
while(files[j].name[0] != '\0'){
if((comparison = strcmp(files[j].name, nameOfProgram)) == 0) {
break;
}
j++;
}
if(comparison == 0){
dou = strstr(line, "[")+1;
int k=0;
while(dou[k] != ']'){
dateOfUpgrade[k] = dou[k];
k++;
}
strcpy(files[j].upgradeDate, dateOfUpgrade);
files[j].upgrades++;
}
upgraded++;
}
//printf("%s\n", line);
}
}
//printf("\n\n%d, %d, %d \n\n", installed, removed, upgraded);
if(close(fd) == -1){
//perror("close");
printf("Unreadable");
exit(1);
}
}
这是我的结构:
struct file{
char name[64];
char installDate[20];
char upgradeDate[20];
char removeDate[20];
int upgrades;
};
struct file files[2048];
我已经发现问题是在使用 snprintf() 函数在写入之前将值传递到 char 数组时出现的:
if(files[j].name[0] != '\0'){
snprintf(input, max_size,
"- Package Name : %s\n"
" - Install date : %s\n"
" - Last update date : %s\n"
" - How many updates : %d\n"
" - Removal date : %s\n",
files[j].name, files[j].installDate,
upD, files[j].upgrades, remD);
}
"files" 数组中的每个数据都使用 '\0' 进行初始化,以保存升级,因为它是一个 int,它被初始化为 0:
for(p=0; p<2048; p++){
files[p].name[0] = '\0';
files[p].installDate[0] = '\0';
files[p].upgradeDate[0] = '\0';
files[p].removeDate[0] = '\0';
files[p].upgrades = 0;
}
有人知道为什么它会在“安装日期”部分发出那些奇怪的字符和重复的日期吗?
解决方案
推荐阅读
- highcharts - 根据不规则数据绘制 Highcharts 热图
- meteor - 如何从命令行调用 Meteor 方法
- spring - Spring OAuth2 在成功验证时重定向到原始 URL
- jquery - 使用 jquery 每 5 秒倒计时
- python - 单从多拆分
- elasticsearch - Elasticsearch 排除对字段值的最高命中
- java - 从数据库 Spring Boot 获取详细信息,异常错误
- swift - 使用 GKStates 和 PhysicsBody 操作的最佳实践
- html - 如何将我的 JSON 文件导入 app.ts 以显示 app.html 中的选项?
- r - 测试字符串是否在字母表的 n 个位置