我想我知道問題是什麼。你永遠不會初始化outputfile
。作爲初學者,您應該在聲明變量時始終初始化變量。從來不寫
int i;
寫
int i = ...;
,並給它一個初始值(0
,-1
,INT_MAX
,不管你喜歡)。這對於指針來說非常重要。如果你寫
FILE * outputfile;
這是指向哪裏的指針?那是隨機的。它可能指向任何地方或無處。這是一個「無效」指針,在任何情況下您都不能使用outputfile
,因爲任何使用的結果都是未定義的。但你怎麼知道它已經初始化?那麼,你不能!你不能,因爲你從來沒有分配任何值你可以檢查。
更好的代碼將
FILE * outputfile = NULL;
像現在outputfile
已定義的值,它是NULL
,這意味着你可以測試,如果它是你的代碼草簽
if (outputfile == NULL) {
// Not initialized
} else {
// Initialized
}
外觀和思考以下內容:
如果循環第一次運行,並且第一個512字節的塊與0xffd8ff..
的if-test不匹配,會發生什麼情況?那麼你在其他情況下結束,這種情況下,以下內容
fwrite(jpg,512,1,outputfile) ;
但在這裏有什麼值outputfile
?沒有價值,它完全沒有定義。您在任何地址訪問內存,這很可能會導致您的應用程序崩潰,這正是發生在您身上的事情。如果你已經初始化outputfile
到NULL
,正確的代碼將是:
} else if (outputfile != NULL) {
fwrite(jpg,512,1,outputfile);
}
這裏來美化超,清理的代碼版本。代碼未經測試,我只知道它編譯。我知道它也變得更大,但請考慮也有很多評論,代碼正在檢查和處理所有預期的錯誤,甚至打印到STDERR
出了什麼問題。如果我想我可以壓縮很容易down to 58 lines,這比在問題你的代碼更只有7行,但您的代碼不捕獲或打印所有這些錯誤:
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
int main (void) {
FILE * inputFile = fopen("card.raw", "r");
if (!inputFile) { // Same as "if (inputFile == NULL)"
fprintf(stderr, "Cannot open input file!\n");
// Don't close it, it didn't open!
return 1;
}
// Always declare variables in the smallest possible scope!
// Don't declare anything here you only need in the loop and
// whose value doesn't need to survive a loop iteration.
int fileCounter = 0;
FILE * outputFile = NULL;
bool writeError = false;
for (;;) { // Endless loop, will never terminate on its own
uint8_t cluster[512];
// It will read one cluster or nothing at all.
if (fread(cluster, sizeof(cluster), 1, inputFile) != 1) {
// If we have an open output file, close it.
if (outputFile) {
fclose(outputFile);
outputFile = NULL; // Not required but good style.
}
break; // Terminates the loop!
// Not reached, code flow continues after the loop.
}
// Check if start of new _or first_ JPG file.
if (cluster[0] == 0xFF && cluster[1] == 0xd8
&& cluster[2] == 0xFF && cluster[3] >= 0xE0 && cluster[3] <= 0xEF
) {
char filename[8];
snprintf(filename, sizeof(filename), "%03d.jpg", fileCounter++);
// Start nof an new JPG file.
// If we have an "old" one, time to close it
if (outputFile) {
fclose(outputFile);
}
// Open new file
outputFile = fopen(filename, "w");
if (!outputFile) {
// Cannot create output file.
writeError = true;
break; // Terminates the loop!
// Not reached, code flow continues after the loop.
}
}
// If we have an output file, write the cluster to it.
if (outputFile) {
if (fwrite(cluster, sizeof(cluster), 1, outputFile) != 1) {
// Write error.
writeError = true;
// Close the file.
fclose(outputFile);
break; // Terminates the loop!
// Not reached, code flow continues after the loop.
}
}
}
// If we end up here, we ran into one of the "breaks"
// and now need to find out which one.
bool exitWithError = false;
if (writeError) {
exitWithError = true;
fprintf(stderr, "Counldn't create/write to output file!\n");
} else if (ferror(inputFile) != 0) {
exitWithError = true;
fprintf(stderr, "Counldn't read from input file file!\n");
}
// Otherwise input file was just at the end.
// Final clanup:
fclose(inputFile);
return (exitWithError ? 1 : 0);
}
我與你分享這個代碼因爲學習某些編碼概念可能是最簡單的,只要看看其他人編寫代碼的方式。
'char filename [7];'對於3 + 1 + 3 + 1個字符太小。 – wildplasser
如果我使用char文件名[8]我得到一個段錯誤 – mithilesh
如果您查看格式化的代碼,您可以看到檢查選定內容的可怕if語句中的差異。這可能會解釋您的部分或全部問題。你應該考慮重構你的代碼;通過'checkjpg16'變量'checkjpg1'肯定看起來像一個僞裝成我的陣列。避免像這樣寫東西;使用數據結構(例如數組 - 一個非常基本的數據結構)來封裝重複。仔細觀察數據時,應該將前3個字節與已知序列進行比較,並檢查第4個是否在範圍內。 –