空间后fgetc无法正确显示

问题描述 投票:2回答:2
    #include <stdio.h> 
    #include <stdlib.h>
    #include <string.h>

    int main() {
      FILE *userfile, *pwfile, *usernamesPasswords, *readUsernamesPasswords;
      char u, p, user[20][25], pass[20][20], userLine[25], passLine[20];
      int i = 0;
      int j = 0;
      int userIndex = 0;
      int passIndex = 0;

      userfile = fopen("usernames.txt", "r");
      pwfile = fopen("passwords.txt", "r");

      if (userfile == NULL || pwfile == NULL) {
        printf("Cannot open file \n");
        exit(0);
      }

      u = fgetc(userfile);
      while (u != EOF) {
        if ( u != '\n'){
          userLine[userIndex++] = u;
        } else {
          userLine[userIndex] = '\0';
          strcpy(user[i], userLine);
          userIndex = 0;
          i++;
        }
        u = fgetc(userfile);
      }
      fclose(userfile);


      p = fgetc(pwfile);
      while (p != EOF) {
        if ( p != '\n'){
           passLine[passIndex++] = p;
        } else {
            passLine[passIndex] = '\0';
            strcpy(pass[j], passLine);
            passIndex = 0;
            j++;
        }
        p = fgetc(pwfile);
      }
      fclose(pwfile);

      usernamesPasswords = fopen("usernamesPasswords.txt", "w");
      int w, k;
      char newLine[1024];
      for (w=0;w<20;w++) {
        strcat(newLine, user[w]);

        int q = strlen(newLine);
        for (k=0;k<(25-q);k++) {
          strcat(newLine, " ");
        }

        strcat(newLine, pass[w]);
        strcat(newLine, "\n");
        strcat(newLine, "\0");
        fputs(newLine ,usernamesPasswords);
        strcpy(newLine, "");
      }
      fclose(usernamesPasswords);

      printf("\nDo you want to display the new file? Enter (y) to view and any other key to exit\n");
      char word;
      scanf("%c",&word);

      if (word == 'y') {
        readUsernamesPasswords = fopen("usernamesPasswords.txt", "r");
        if (readUsernamesPasswords == NULL) {
          printf("Cannot open file \n");
          exit(0);
        }

        char r;
        while((r=fgetc(readUsernamesPasswords))!=EOF) {
          printf("%c", r);
        }
        fclose(readUsernamesPasswords);
      }

      return 0;
    }

预期产出:

Moodie                  123456
Intelllligent           password
Happee                  12345678
Mischeivous             qwerty
SweetKristy             123456789
KristyHoney             12345
BubblySnowflake         1234
AngelicPrincessKristy   111111
FairyPrincessKristy     1234567
BabyKristyButterfly     dragon
daffyusers              123123
magpiedoodle            baseball
aspiringthreat          abc123
landmarksspreader       football
cavaliervanquish        monkey
chatteringparma         letmein
veggiehydrogen          696969
teethunsure             shadow
rumpboast               master
lidarstrudel            666666

代替...

                  123456
           password
                  12345678
             qwerty
             123456789
             12345
         1234ke
   111111incessKristy
     1234567sKristy
     dragonutterfly
              123123
            baseball
          abc123
       footballer
        monkeysh
         letmein
          696969
             shadow
               master
            666666

这只发生在我尝试在终端上输出时。实际的usernamesPasswords.txt文件按预期出现。字符串的左侧似乎只有在我换行代替空格时才能打印出来...

我甚至试过fgets和fread但是输出相似。我已经阅读了有关吃或消费的其他帖子,所以我尝试使用fgets或fread按照建议,甚至尝试unget。似乎没有用。我一直在寻找堆栈溢出无济于事。

如果这是重复,我在高级道歉。在决定发布之前,我真的试着在网上看几个小时。

我通常不发布cuz堆栈溢出通常已经拥有一切...

请帮忙!谢谢!

c file fgets cs50 fgetc
2个回答
2
投票

你不能在未初始化的存储上调用strcatstrlen。这是未定义的行为。字符串函数通常要求输入字符串参数正确地以NUL方式终止。 (没有终结符,就无法分辨字符串的结束位置。)

strcat(s, "\0")是一个无操作,因为第二个参数实际上是一个空(零长度)字符串。 (并且,如上所述,如果s尚未以NUL终止,则为未定义行为。)


0
投票

在您的程序中,这部分代码几乎没有问题:

  char newLine[1024];
  for (w=0;w<20;w++) {
    strcat(newLine, user[w]);

    int q = strlen(newLine);
    for (k=0;k<(25-q);k++) {
      strcat(newLine, " ");
    }

    strcat(newLine, pass[w]);
    strcat(newLine, "\n");
    strcat(newLine, "\0");
    fputs(newLine ,usernamesPasswords);
    strcpy(newLine, "");
  }

newLine缓冲区这样的问题没有初始化并在strcat中使用。连接空字符串没有效果 - strcat(newLine, "\0");。您可以通过简单地使用{0}初始化缓冲区来解决这些问题,而不是连接空字符串,在适当的缓冲区索引处分配\0。但是你不需要做所有这些strcat,而只需要在这样的一行中完成所有这些:

  char newLine[1024];
  for (w=0;w<20;w++) {
    snprintf (newLine, 1024, "%-25s%s\n", user[w], pass[w]);
    fputs(newLine ,usernamesPasswords);
  }

snprintf在写入缓冲区的内容后附加一个终止空字符。

几点: - 你应该检查fopen的返回值。 - fgetc的返回类型是int而不是char,你正在以char类型获取其返回值。 - 你需要在你的程序中处理一些事情,比如你的程序是在假设usernames.txtpasswords.txt包含精确的20行的情况下工作的。最好让它变得灵活。

© www.soinside.com 2019 - 2024. All rights reserved.