首页 > 解决方案 > 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;
}

有人知道为什么它会在“安装日期”部分发出那些奇怪的字符和重复的日期吗?

标签: cprintfsymbols

解决方案


推荐阅读