空间

时间:2018-02-10 05:04:18

标签: c file fgets cs50 fgetc

    #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堆栈溢出通常已经拥有一切...

请帮忙!谢谢!

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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行的假设下工作。最好让它变得灵活。