我正试图用C编写一个基本的变体测试脚本,但我遇到了一些错误,似乎无法解决。首先要评论的是,在似乎有问题的函数中,namr,我试图使用一个简单的凯撒密码来命名我正在创建的文件,以避免在文件名中包含不需要的字符。当我按原样运行它时,字符串cexp和mcexp有时似乎从我在另一个函数switcher中读取的文件中获取内容。当我在Annotation 1添加printf时,它似乎运行得很好,但文件名出现了错误。尽管如此,如果我将Annotation 1注释掉,则会出现malloc((:损坏的顶部大小错误。我试过各种印刷品,看看出了什么问题。到了注释2时,cexp和mcexp仍然是所需的长度和内容,但到了注释3时,它们已经有26或25个字符长,并且在脚本的其他部分包含了我正在读取的文件的起始行。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *namr(char *exp, char *mexp, int ignv) {
int explen = strlen(exp);
int mexplen = strlen(mexp);
//printf("EXPLEN: %d MEXPLEN: %dn",explen,mexplen);
//ANNOTATION 1
char *cexp = (char *)malloc(explen + 1);
char *cmexp = (char *)malloc(mexplen + 1); //Exp in Caeser Cipher
for (int i = 0; i < explen; i++) {
cexp[i]= (exp[i] ? 'A' + exp[i] % 25 : exp[i]);
printf("%d - %c - %cn", i, exp[i], 'A' + exp[i] % 25);
//ANNOTATION 2
}
for (int i = 0; i < mexplen; i++) {
cmexp[i]= (mexp[i] ? 'A' + mexp[i] % 25 : mexp[i]);
}
printf("EXP: %snMEXP: %sn", exp, mexp);
printf("CEXP: %snCMEXP: %sn", cexp, cmexp);
//ANNOTATION 3
printf("%s - %dn%s - %dn%dn", cexp, strlen(cexp),
cmexp, strlen(cmexp), strlen("./U_SWITCH_MTNTS/TO%03.c"));
char *outname = (char *)malloc((30 + explen + mexplen));
sprintf(outname, "./U_SWITCH_MTNTS/%sTO%s%03d.c", cexp, cmexp, ignv);
free(cexp);
free(cmexp);
return outname;
}
int countr(char *filename, char *exp) {
int out = 0;
int i, flag;
int inlen = strlen(exp);
char c;
FILE *f = fopen(filename, "r");
while (c != EOF) {
for (i = 0, flag = 0; i < inlen; i++) {
if (exp[i] != c) {
flag = 1;
break;
}
c = getc(f);
}
if (flag == 0)
out++;
c = getc(f);
}
fclose(f);
return out;
}
char *switchr(char *filename, char *exp, char *mexp, int ignv) {
int i, flag,buffcount;
FILE *f = fopen(filename, "r");
char *outname = namr(exp, mexp, ignv);
FILE *fout = fopen(outname, "w");
char c = getc(f);
int ignc = ignv;
int inlen = strlen(exp);
char *buffer = (char *)malloc(inlen * sizeof(char));
while (c != EOF) {
for (i = 0, flag = 0, buffcount = 0; i < inlen; i++) {
if (exp[i] != c) {
flag = 1;
break;
} else {
buffer[buffcount] = c;
buffcount++;
c = getc(f);
}
}
if (flag == 0) {
if(ignc == 0) {
fputs(mexp, fout);
} else {
for (i = 0; i < buffcount; i++)
fputc(buffer[i], fout);
}
ignc--;
} else {
for (i = 0; i < buffcount; i++)
fputc(buffer[i], fout);
}
fputc(c, fout);
c = getc(f);
}
fclose(f);
fclose(fout);
return outname;
}
void mstrswitch(char *filename) {
int ecount = countr(filename, "==");
char **filenames = (char **)malloc(5 * ecount * sizeof(char *));
char command[100];
system("mkdir U_SWITCH_MTNTS");
system("mkdir TEST_OBJECTS");
for (int i = 0;i < ecount; i++) {
filenames[5 * i] = switchr("test.c", "==", "<=", i);
filenames[5 * i + 1] = switchr("test.c", "==", ">=", i);
filenames[5 * i + 2] = switchr("test.c", "==", ">", i);
filenames[5 * i + 3] = switchr("test.c", "==", "<", i);
filenames[5 * i + 4] = switchr("test.c", "==", "!=", i);
}
for (int i = 0; i < 5 * ecount; i++) {
sprintf(command, "gcc -o ./TEST_OBJECTS/test%03d %s", i, filenames[i]);
system(command);
sprintf(command, "./TEST_OBJECTS/test%03d", i);
system(command);
free(filenames[i]);
}
free(filenames);
}
int main() {
mstrswitch("test.c");
return 0;
}
永远不会零终止字符串cexp
和cmexp
。所以加上这两行:
for(int i=0;i<explen;i++)
{
cexp[i]= (exp[i]?'A'+exp[i]%25: exp[i]);
printf("%d - %c - %cn",i,exp[i],'A'+exp[i]%25);
}
cexp[explen]= ' '; <------------------- add
for(int i=0;i<mexplen;i++)
{
cmexp[i]= (mexp[i]?'A'+mexp[i]%25: mexp[i]);
}
cmexp[mexplen]= ' '; <------------------- add
此外,下面的行看起来很奇怪:
cexp[i]= (exp[i]?'A'+exp[i]%25: exp[i]);
^^^^^^
Always true
拥有一个总是返回true的条件可能不是你想要的。