我的解码器出了什么问题?为什么在提示用户后它会冻结?

时间:2015-06-10 22:38:11

标签: c debugging prompt freeze

目标是提示用户编码输入文件并将代码写入输出文件或解码输入文件并将消息写入输出文件。每当我运行程序时,虽然它编译,但只要输入提示字符就会停止响应。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>

int encode(FILE * fp1, FILE * fp2);
int decode(FILE * fp1, FILE * fp2);
int main() {
       char prompt;
       printf("Would you like to encode a message into a file?\n");
       printf("Or would you like to decode a message from a file?\n");
       printf("Enter e to encode or d to decode.\n");
       scanf("%c", prompt);
       FILE *fp1, *fp2;
       char filename1[INT_MAX], filename2[INT_MAX];
       printf("Enter input file: ");
       scanf("%s", filename1);
       fp1 = fopen(filename1, "r");
       printf("Enter output file: ");
       scanf("%s", filename2);
       fp2 = fopen(filename2, "w");
       if (fp1 == NULL) {
               printf("The file does not exist.\n");
               return 0;
       }
       if (fp2 == NULL) {
               printf("The file oes not exist.\n");
               return 0;
       }
       switch (prompt) {
              case 'e':
                   encode(fp1, fp2);
                   break;
              case 'E':
                   encode(fp1, fp2);
                   break;
              case 'd':
                   decode(fp1, fp2);
                   break;
              case 'D':
                   decode(fp1, fp2);
                   break;
              default:
                      break;
       }
       return 0;
    }

int encode(FILE * fp1, FILE * fp2) {
     char ci, co;
     while (fscanf(fp1, "%c", ci) != EOF) {
           for (ci = 97; ci <= 122; ci++)
               co = ci - 64;
           for (ci = 48; ci <= 57; ci++)
               co = ci + 11;
           switch (ci) {
                case 32:
                     co = 69;
                     break;
                case 10:
                     co = 70;
                     break;
                case 13:
                     co = 71;
                     break;
                default:
                     break;
           }
           fprintf(fp2, "%c", co);
     } 
     printf("Your message has been encoded.\n");
     system("pause");
     return 0;
} 

int decode(FILE * fp1, FILE * fp2) {
     char ci, co;
     while (fscanf(fp1, "%c", ci) != EOF) {
           for (ci = 33; ci <= 58; ci++)
               co = ci + 64;
           for (ci = 59; ci <= 68; ci++)
               co = ci - 11;
           switch(ci) {
                case 69:
                     co = 32;
                     break;
                case 70:
                     co = 10;
                     break;
                case 71:
                     co = 13;
                     break;
                default:
                     break;
           }
           fprintf(fp2, "%c", co);
     } 
     printf("Your message has been decoded.\n");
     system("pause");
     return 0;
}

2 个答案:

答案 0 :(得分:4)

可能还有其他问题,但第一个问题在这里:

scanf("%c", prompt);

应该是

scanf("%c", &prompt);

查看完整的函数定义和示例here

此外,

char filename1[INT_MAX], filename2[INT_MAX];

这不是一个好主意。动态分配或至少为文件名使用更合理的数字。 256应该足够的文件名。如果您真的担心作业中的缓冲区溢出,可以使用提及here的技术为输入字符串正确分配内存(只要您使用的是GNU编译器):

char *str;
printf("Enter your filename:\n");
scanf("%ms", &str);

printf("Hello %s!\n", str);
free(str);

%m将自动分配一个适当大小的字符串,以避免缓冲区溢出。

这只是为了便于阅读:

    switch (prompt) {
    case 'e':
        encode(fp1, fp2);
        break;
    case 'E':
        encode(fp1, fp2);
        break;
    case 'd':
        decode(fp1, fp2);
        break;
    case 'D':
        decode(fp1, fp2);
        break;
    default:
        break;
}

可以缩减为:

switch (prompt) {
    case 'e':
    case 'E':
        encode(fp1, fp2);
        break;
    case 'd':
    case 'D':
        decode(fp1, fp2);
        break;
    default:
        break;
}

答案 1 :(得分:1)

<强>第一

对于第二个参数,

scanf应该有一个引用char地址。您正在传递其。 rost0031在他的回答中提到了这一点。

<强>第二

您很可能会在堆栈上实例化char的大数组时收到 Stack Overflow 。所以请改为:

char* filename1 = malloc(INT_MAX);
char *filename2 = malloc(INT_MAX);

如果你不知道malloc做了什么,它基本上上动态分配内存(这比堆栈)。 这些分配要求您在完成使用后free内存(否则您将内存泄漏):

free(filename1);
free(filename2);

<强>第三

您的decodeencode函数无需返回int,因为您没有返回任何有用的内容,而且您的调用不会产生结果。您可以在范围结束前制作void并删除return 0;

void decode(FILE * fp1, FILE * fp2);
void encode(FILE * fp1, FILE * fp2);