问题
I know I really shouldn't ask for bug solutions here in Stack exchange, but I'm new to C and I made a program that unrolls code and prints the code out in a .c file. The problem is that when I want to print out some lines of code, the fputs
function to codeOutput crashes the program(I've debugged it this far). I've tried changing the codeOutput file from .c to .txt, but it hasn't changed anything. I know this code excerpt is not really repeatable, but I'm sure I just made a dumb mistake in writing the code. heres my code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
char buf[500];
int numberOfSamples = 5;
int numberOfElements = 10;
int currentTest = 1;
FILE *arrayAssignmentReader[numberOfSamples];
FILE *codeSnippetReader[numberOfSamples];
FILE *arrayPrintReader[numberOfSamples];
FILE *codeOutput[numberOfSamples];
for (int i = 0; i < numberOfSamples; i++) {
sprintf(buf, "C:/Users/Erlandas/Desktop/Research/C/TestNo%i/ProgramNo1/SampleNo%i/ArrayAssignment.txt", currentTest, i);
arrayAssignmentReader[i] = fopen(buf, "r+");
sprintf(buf, "C:/Users/Erlandas/Desktop/Research/C/TestNo%i/ProgramNo2/SampleNo%i/codeSnippet.txt", currentTest, i);
codeSnippetReader[i] = fopen(buf, "r+");
sprintf(buf, "C:/Users/Erlandas/Desktop/Research/C/TestNo%i/ProgramNo1/SampleNo%i/ProgramNo1PrintArray.txt", currentTest, i);
arrayPrintReader[i] = fopen(buf, "r+");
sprintf(buf, "C:/Users/Erlandas/Desktop/Research/C/TestNo%i/codeForNo3/codeNo%i/", currentTest, i);
struct stat st = {0};
if (stat(buf, &st) == -1) {
mkdir(buf);
}
sprintf(buf, "C:/Users/Erlandas/Desktop/Research/C/TestNo%i/codeForNo3/CodeNo%i/CodeNo%i.c", currentTest, i, i);
codeOutput[i] = fopen(buf, "w+");
}
for (int currentSample = 0; currentSample < numberOfSamples; currentSample++) {
sprintf(buf, "#include <stdio.h>\n#include <time.h>\n#include <stdlib.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <math.h>\n#include <unistd.h>\n#define BILLION 1000000000L\nint main()\n{\nchar buf[500];\nint numberOfElements = %i;\nint currentTest = %i;\nint randomArray[numberOfElements];\nint minIndex;\nint minValue;\nstruct timespec requestStart;\nstruct timespec requestEnd;\nlong int recordStartTime;\nlong int recordEndTime;\nlong int elapsedTime;\nFILE *arrangedArray;\nFILE *stopwatch;\nsprintf(buf,\"C:/Users/Erlandas/Desktop/Research/C/TestNo%%i/ProgramNo3/ProgramNo3Stopwatch.txt\", currentTest);\nstopwatch = fopen(buf, \"a+\");\nstruct stat st = {0};\nsprintf(buf, \"C:/Users/Erlandas/Desktop/Research/C/TestNo%%i/ProgramNo3/\", currentTest);\nif (stat(buf, &st) == -1)\n{\nsprintf(buf, \"C:/Users/Erlandas/Desktop/Research/C/TestNo%%i/ProgramNo3/\", currentTest);\nmkdir(buf);\n}\nsprintf(buf, \"C:/Users/Erlandas/Desktop/Research/C/TestNo%%i/CodeForNo3/SampleNo%i/ArrangedArray.txt\", currentTest, currentSample);\narrangedArray = fopen(buf, \"w+\");\n", numberOfElements, currentTest, currentSample);
fputs(buf, codeOutput[currentSample]);
while (buf[0] != EOF){
fgets(buf, 500, arrayAssignmentReader[currentSample]);
fputs(buf, codeOutput[currAentSample]);
fputs("\n", codeOutput[currentSample]);
}
sprintf(buf, "clock_gettime(CLOCK_MONOTONIC, &requestStart);\nrecordStartTime = requestStart.tv_nsec + requestStart.tv_sec * BILLION;\n");
fputs(buf, codeOutput[currentSample]);
while (buf[0] != EOF) {
fgets(buf, 500, codeSnippetReader[currentSample]);
fputs(buf, codeOutput[currentSample]);
fputs("\n", codeOutput[currentSample]);
}
sprintf(buf, "clock_gettime(CLOCK_MONOTONIC, &requestEnd);\nrecordEndTime = (requestEnd.tv_nsec + requestEnd.tv_sec * BILLION);\nelapsedTime = recordEndTime - recordStartTime;\nsprintf(buf, \"%%li\\n\", elapsedTime);\nfputs(buf, stopwatch);\n");
fputs(buf, codeOutput[currentSample]);
while (buf[0] != EOF) {
fgets(buf, 500, arrayPrintReader[currentSample]);
fputs(buf, codeOutput[currentSample]);
fputs("\n", codeOutput[currentSample]);
}
sprintf(buf, "\nfclose(output);\nfclose(arrayOutput);\nfclose(arrangedArray);\n}\nfclose(stopwatch);\nreturn 0;\n}\n");
fputs(buf, codeOutput[currentSample]);
}
return 0;
}
回答1:
buf
is not large enough for this statement:
sprintf(buf, "#include <stdio.h>\n#include <time.h>\n#include <stdlib.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <math.h>\n#include <unistd.h>\n#define BILLION 1000000000L\nint main()\n{\nchar buf[500];\nint numberOfElements = %i;\nint currentTest = %i;\nint randomArray[numberOfElements];\nint minIndex;\nint minValue;\nstruct timespec requestStart;\nstruct timespec requestEnd;\nlong int recordStartTime;\nlong int recordEndTime;\nlong int elapsedTime;\nFILE *arrangedArray;\nFILE *stopwatch;\nsprintf(buf,\"C:/Users/Erlandas/Desktop/Research/C/TestNo%%i/ProgramNo3/ProgramNo3Stopwatch.txt\", currentTest);\nstopwatch = fopen(buf, \"a+\");\nstruct stat st = {0};\nsprintf(buf, \"C:/Users/Erlandas/Desktop/Research/C/TestNo%%i/ProgramNo3/\", currentTest);\nif (stat(buf, &st) == -1)\n{\nsprintf(buf, \"C:/Users/Erlandas/Desktop/Research/C/TestNo%%i/ProgramNo3/\", currentTest);\nmkdir(buf);\n}\nsprintf(buf, \"C:/Users/Erlandas/Desktop/Research/C/TestNo%%i/CodeForNo3/SampleNo%i/ArrangedArray.txt\", currentTest, currentSample);\narrangedArray = fopen(buf, \"w+\");\n", numberOfElements, currentTest, currentSample);
You should make buf
much larger and use snprintf()
to avoid buffer overflows.
You should break all these strings into fragments that fit on regular lines:
sprintf(buf, "clock_gettime(CLOCK_MONOTONIC, &requestEnd);\n"
"recordEndTime = (requestEnd.tv_nsec + requestEnd.tv_sec * BILLION);\n"
"elapsedTime = recordEndTime - recordStartTime;\n"
"sprintf(buf, \"%%li\\n\", elapsedTime);\n"
"fputs(buf, stopwatch);\n");
fputs(buf, codeOutput[currentSample]);
But note however that you do not need sprintf()
at all for some of these: since you are not substituting any variables, so you could just call fputs
with the string directly.
Furthermore, the way you test for end of file is incorrect: while (buf[0] != EOF)
cannot test if you have reached the end of file, checking the return value of fgets()
is the correct way to do this:
while (fgets(buf, 500, arrayAssignmentReader[currentSample]) != NULL) {
fputs(buf, codeOutput[currentSample]);
fputs("\n", codeOutput[currentSample]);
}
回答2:
You should be checking the result of the fopen() function to make sure it is not NULL:
codeOutput[i] = fopen(buf, "w+");
if (codeOutput[i] == NULL) {
perror(buf); /* Assuming perror is supported and you
#include <errno.h> */
exit();
}
来源:https://stackoverflow.com/questions/40432898/why-does-my-program-crash-upon-writing-to-a-file