其實之前就已經修完 CS50 了,不過因應 2022 年將課堂作業的系統
從 c9.io 換到 github codespace + vscode 整合
打算來重溫一下裡面的作業,並暖身一下 C 語言的手感
由於已經有許多前輩分享課程與作業的心得
加上官網教材的投影片、重點筆記、教學影片都非常完整
故不再做詳細的紀錄,專注在作業 (Lab, Problem sets) 上面
https://cs50.harvard.edu/x/2022/weeks/4/
style50
風格的程式碼// Modifies the volume of an audio file
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// Number of bytes in .wav header
const int HEADER_SIZE = 44;
int main(int argc, char *argv[])
{
// Check command-line arguments
if (argc != 4)
{
printf("Usage: ./volume input.wav output.wav factor\n");
return 1;
}
// Open files and determine scaling factor
FILE *input = fopen(argv[1], "r");
if (input == NULL)
{
printf("Could not open file.\n");
return 1;
}
FILE *output = fopen(argv[2], "w");
if (output == NULL)
{
printf("Could not open file.\n");
return 1;
}
float factor = atof(argv[3]);
uint8_t header[HEADER_SIZE];
fread(&header, sizeof(header), 1, input);
fwrite(&header, sizeof(header), 1, output);
int16_t buffer;
while (fread(&buffer, sizeof(buffer), 1, input))
{
buffer *= factor;
fwrite(&buffer, sizeof(buffer), 1, output);
}
// Close files
fclose(input);
fclose(output);
}
–
–
執行
Learn More →
驗證
Learn More →
style50
風格的程式碼#include "helpers.h"
#include <math.h>
#include <stdbool.h>
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
int avgRGB;
// iterate the height
for (int i = 0; i < height; i++)
{
// iterate the width
for (int j = 0; j < width; j++)
{
int Red = image[i][j].rgbtRed;
int Green = image[i][j].rgbtGreen;
int Blue = image[i][j].rgbtBlue;
avgRGB = round((Red + Green + Blue) / (float) 3);
image[i][j].rgbtRed = avgRGB;
image[i][j].rgbtGreen = avgRGB;
image[i][j].rgbtBlue = avgRGB;
}
}
return;
}
// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
int originRed, originGreen, originBlue;
int sepiaRed, sepiaBlue, sepiaGreen;
// iterate the height
for (int i = 0; i < height; i++)
{
// iterate the width
for (int j = 0; j < width; j++)
{
originRed = image[i][j].rgbtRed;
originGreen = image[i][j].rgbtGreen;
originBlue = image[i][j].rgbtBlue;
sepiaRed = round(0.393 * originRed + 0.769 * originGreen + 0.189 * originBlue);
sepiaGreen = round(0.349 * originRed + 0.686 * originGreen + 0.168 * originBlue);
sepiaBlue = round(0.272 * originRed + 0.534 * originGreen + 0.131 * originBlue);
image[i][j].rgbtRed = (sepiaRed > 255) ? 255 : sepiaRed;
image[i][j].rgbtGreen = (sepiaGreen > 255) ? 255 : sepiaGreen;
image[i][j].rgbtBlue = (sepiaBlue > 255) ? 255 : sepiaBlue;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
// iterate the height
for (int i = 0; i < height; i++)
{
// iterate the `half of width`
for (int j = 0; j < (width / 2); j++)
{
// get temp color in pixel
int tempRed = image[i][j].rgbtRed;
int tempGreen = image[i][j].rgbtGreen;
int tempBlue = image[i][j].rgbtBlue;
// then swap color from reflect pixel
image[i][j].rgbtRed = image[i][width - j - 1].rgbtRed;
image[i][j].rgbtGreen = image[i][width - j - 1].rgbtGreen;
image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue;
// record temp color to reflect pixel
image[i][width - j - 1].rgbtRed = tempRed;
image[i][width - j - 1].rgbtGreen = tempGreen;
image[i][width - j - 1].rgbtBlue = tempBlue;
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// create a temp image to record blurred pixel
RGBTRIPLE tempImage[height][width];
// iterate the height
for (int i = 0; i < height; i++)
{
// iterate the width
for (int j = 0; j < width; j++)
{
int totalRed = 0;
int totalGreen = 0;
int totalBlue = 0;
int counter = 0;
// get the near 9 pixels
for (int x = -1; x < 2; x++)
{
for (int y = -1; y < 2; y++)
{
int nearX = i + x;
int nearY = j + y;
// check is valid the near pixels
bool invalidX = nearX < 0 || nearX > (height - 1);
bool invalidY = nearY < 0 || nearY > (width - 1);
if (invalidX || invalidY)
{
continue; // skip this round, next iterator
}
// records the pixels value
totalRed += image[nearX][nearY].rgbtRed;
totalGreen += image[nearX][nearY].rgbtGreen;
totalBlue += image[nearX][nearY].rgbtBlue;
counter++;
}
}
// count the avg of near pixels, and record to temp
tempImage[i][j].rgbtRed = round(totalRed / (float) counter);
tempImage[i][j].rgbtGreen = round(totalGreen / (float) counter);
tempImage[i][j].rgbtBlue = round(totalBlue / (float) counter);
}
}
// replace the blurred image to the original image
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j].rgbtRed = tempImage[i][j].rgbtRed;
image[i][j].rgbtGreen = tempImage[i][j].rgbtGreen;
image[i][j].rgbtBlue = tempImage[i][j].rgbtBlue;
}
}
return;
}
–
#include "helpers.h"
#include <math.h>
#include <stdbool.h>
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
int avgRGB;
// iterate the height
for (int i = 0; i < height; i++) {
// iterate the width
for (int j = 0; j < width; j++) {
int Red = image[i][j].rgbtRed;
int Green = image[i][j].rgbtGreen;
int Blue = image[i][j].rgbtBlue;
avgRGB = round((Red + Green + Blue) / (float) 3);
image[i][j].rgbtRed = avgRGB;
image[i][j].rgbtGreen = avgRGB;
image[i][j].rgbtBlue = avgRGB;
}
}
return;
}
// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
int originRed, originGreen, originBlue;
int sepiaRed, sepiaBlue, sepiaGreen;
// iterate the height
for (int i = 0; i < height; i++) {
// iterate the width
for (int j = 0; j < width; j++) {
originRed = image[i][j].rgbtRed;
originGreen = image[i][j].rgbtGreen;
originBlue = image[i][j].rgbtBlue;
sepiaRed = round(0.393 * originRed + 0.769 * originGreen + 0.189 * originBlue);
sepiaGreen = round(0.349 * originRed + 0.686 * originGreen + 0.168 * originBlue);
sepiaBlue = round(0.272 * originRed + 0.534 * originGreen + 0.131 * originBlue);
image[i][j].rgbtRed = (sepiaRed > 255) ? 255 : sepiaRed;
image[i][j].rgbtGreen = (sepiaGreen > 255) ? 255 : sepiaGreen;
image[i][j].rgbtBlue = (sepiaBlue > 255) ? 255 : sepiaBlue;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
// iterate the height
for (int i = 0; i < height; i++) {
// iterate the `half of width`
for (int j = 0; j < (width / 2); j++) {
// get temp color in pixel
int tempRed = image[i][j].rgbtRed;
int tempGreen = image[i][j].rgbtGreen;
int tempBlue = image[i][j].rgbtBlue;
// then swap color from reflect pixel
image[i][j].rgbtRed = image[i][width - j - 1].rgbtRed;
image[i][j].rgbtGreen = image[i][width - j - 1].rgbtGreen;
image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue;
// record temp color to reflect pixel
image[i][width - j - 1].rgbtRed = tempRed;
image[i][width - j - 1].rgbtGreen = tempGreen;
image[i][width - j - 1].rgbtBlue = tempBlue;
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// create a temp image to record blurred pixel
RGBTRIPLE tempImage[height][width];
// iterate the height
for (int i = 0; i < height; i++) {
// iterate the width
for (int j = 0; j < width; j++) {
int totalRed = 0;
int totalGreen = 0;
int totalBlue = 0;
int counter = 0;
// get the near 9 pixels
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
int nearX = i + x;
int nearY = j + y;
// check is valid the near pixels
bool invalidX = nearX < 0 || nearX > (height - 1);
bool invalidY = nearY < 0 || nearY > (width - 1);
if (invalidX || invalidY)
continue; // skip this round, next iterator
// records the pixels value
totalRed += image[nearX][nearY].rgbtRed;
totalGreen += image[nearX][nearY].rgbtGreen;
totalBlue += image[nearX][nearY].rgbtBlue;
counter++;
}
}
// count the avg of near pixels, and record to temp
tempImage[i][j].rgbtRed = round(totalRed / (float) counter);
tempImage[i][j].rgbtGreen = round(totalGreen / (float) counter);
tempImage[i][j].rgbtBlue = round(totalBlue / (float) counter);
}
}
// replace the blurred image to the original image
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
image[i][j].rgbtRed = tempImage[i][j].rgbtRed;
image[i][j].rgbtGreen = tempImage[i][j].rgbtGreen;
image[i][j].rgbtBlue = tempImage[i][j].rgbtBlue;
}
}
return;
}
–
執行
Learn More →
驗證
Learn More →
style50
風格的程式碼#include "helpers.h"
#include <math.h>
#include <stdbool.h>
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
int avgRGB;
// iterate the height
for (int i = 0; i < height; i++)
{
// iterate the width
for (int j = 0; j < width; j++)
{
int Red = image[i][j].rgbtRed;
int Green = image[i][j].rgbtGreen;
int Blue = image[i][j].rgbtBlue;
avgRGB = round((Red + Green + Blue) / (float) 3);
image[i][j].rgbtRed = avgRGB;
image[i][j].rgbtGreen = avgRGB;
image[i][j].rgbtBlue = avgRGB;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
// iterate the height
for (int i = 0; i < height; i++)
{
// iterate the `half of width`
for (int j = 0; j < (width / 2); j++)
{
// get temp color in pixel
int tempRed = image[i][j].rgbtRed;
int tempGreen = image[i][j].rgbtGreen;
int tempBlue = image[i][j].rgbtBlue;
// then swap color from reflect pixel
image[i][j].rgbtRed = image[i][width - j - 1].rgbtRed;
image[i][j].rgbtGreen = image[i][width - j - 1].rgbtGreen;
image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue;
// record temp color to reflect pixel
image[i][width - j - 1].rgbtRed = tempRed;
image[i][width - j - 1].rgbtGreen = tempGreen;
image[i][width - j - 1].rgbtBlue = tempBlue;
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// create a temp image to record blurred pixel
RGBTRIPLE tempImage[height][width];
// iterate the height
for (int i = 0; i < height; i++)
{
// iterate the width
for (int j = 0; j < width; j++)
{
int totalRed = 0;
int totalGreen = 0;
int totalBlue = 0;
int counter = 0;
// get the near 9 pixels
for (int x = -1; x < 2; x++)
{
for (int y = -1; y < 2; y++)
{
int nearX = i + x;
int nearY = j + y;
// check is valid the near pixels
bool invalidX = nearX < 0 || nearX > (height - 1);
bool invalidY = nearY < 0 || nearY > (width - 1);
if (invalidX || invalidY)
{
continue; // skip this round, next iterator
}
// records the pixels value
totalRed += image[nearX][nearY].rgbtRed;
totalGreen += image[nearX][nearY].rgbtGreen;
totalBlue += image[nearX][nearY].rgbtBlue;
counter++;
}
}
// count the avg of near pixels, and record to temp
tempImage[i][j].rgbtRed = round(totalRed / (float) counter);
tempImage[i][j].rgbtGreen = round(totalGreen / (float) counter);
tempImage[i][j].rgbtBlue = round(totalBlue / (float) counter);
}
}
// replace the blurred image to the original image
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j].rgbtRed = tempImage[i][j].rgbtRed;
image[i][j].rgbtGreen = tempImage[i][j].rgbtGreen;
image[i][j].rgbtBlue = tempImage[i][j].rgbtBlue;
}
}
return;
}
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE temp[height][width];
int gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
int gy[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
int gxBlue = 0;
int gyBlue = 0;
int gxGreen = 0;
int gyGreen = 0;
int gxRed = 0;
int gyRed = 0;
for (int r = -1; r < 2; r++)
{
for (int c = -1; c < 2; c++)
{
if (i + r < 0 || i + r > height - 1)
{
continue;
}
if (j + c < 0 || j + c > width - 1)
{
continue;
}
gxBlue += image[i + r][j + c].rgbtBlue * gx[r + 1][c + 1];
gyBlue += image[i + r][j + c].rgbtBlue * gy[r + 1][c + 1];
gxGreen += image[i + r][j + c].rgbtGreen * gx[r + 1][c + 1];
gyGreen += image[i + r][j + c].rgbtGreen * gy[r + 1][c + 1];
gxRed += image[i + r][j + c].rgbtRed * gx[r + 1][c + 1];
gyRed += image[i + r][j + c].rgbtRed * gy[r + 1][c + 1];
}
}
int blue = round(sqrt(gxBlue * gxBlue + gyBlue * gyBlue));
int green = round(sqrt(gxGreen * gxGreen + gyGreen * gyGreen));
int red = round(sqrt(gxRed * gxRed + gyRed * gyRed));
temp[i][j].rgbtBlue = (blue > 255) ? 255 : blue;
temp[i][j].rgbtGreen = (green > 255) ? 255 : green;
temp[i][j].rgbtRed = (red > 255) ? 255 : red;
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
image[i][j].rgbtBlue = temp[i][j].rgbtBlue;
image[i][j].rgbtGreen = temp[i][j].rgbtGreen;
image[i][j].rgbtRed = temp[i][j].rgbtRed;
}
}
return;
}
–
#include "helpers.h"
#include <math.h>
#include <stdbool.h>
// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
int avgRGB;
// iterate the height
for (int i = 0; i < height; i++) {
// iterate the width
for (int j = 0; j < width; j++) {
int Red = image[i][j].rgbtRed;
int Green = image[i][j].rgbtGreen;
int Blue = image[i][j].rgbtBlue;
avgRGB = round((Red + Green + Blue) / (float) 3);
image[i][j].rgbtRed = avgRGB;
image[i][j].rgbtGreen = avgRGB;
image[i][j].rgbtBlue = avgRGB;
}
}
return;
}
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
// iterate the height
for (int i = 0; i < height; i++) {
// iterate the `half of width`
for (int j = 0; j < (width / 2); j++) {
// get temp color in pixel
int tempRed = image[i][j].rgbtRed;
int tempGreen = image[i][j].rgbtGreen;
int tempBlue = image[i][j].rgbtBlue;
// then swap color from reflect pixel
image[i][j].rgbtRed = image[i][width - j - 1].rgbtRed;
image[i][j].rgbtGreen = image[i][width - j - 1].rgbtGreen;
image[i][j].rgbtBlue = image[i][width - j - 1].rgbtBlue;
// record temp color to reflect pixel
image[i][width - j - 1].rgbtRed = tempRed;
image[i][width - j - 1].rgbtGreen = tempGreen;
image[i][width - j - 1].rgbtBlue = tempBlue;
}
}
return;
}
// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
// create a temp image to record blurred pixel
RGBTRIPLE tempImage[height][width];
// iterate the height
for (int i = 0; i < height; i++) {
// iterate the width
for (int j = 0; j < width; j++) {
int totalRed = 0;
int totalGreen = 0;
int totalBlue = 0;
int counter = 0;
// get the near 9 pixels
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
int nearX = i + x;
int nearY = j + y;
// check is valid the near pixels
bool invalidX = nearX < 0 || nearX > (height - 1);
bool invalidY = nearY < 0 || nearY > (width - 1);
if (invalidX || invalidY)
continue; // skip this round, next iterator
// records the pixels value
totalRed += image[nearX][nearY].rgbtRed;
totalGreen += image[nearX][nearY].rgbtGreen;
totalBlue += image[nearX][nearY].rgbtBlue;
counter++;
}
}
// count the avg of near pixels, and record to temp
tempImage[i][j].rgbtRed = round(totalRed / (float) counter);
tempImage[i][j].rgbtGreen = round(totalGreen / (float) counter);
tempImage[i][j].rgbtBlue = round(totalBlue / (float) counter);
}
}
// replace the blurred image to the original image
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
image[i][j].rgbtRed = tempImage[i][j].rgbtRed;
image[i][j].rgbtGreen = tempImage[i][j].rgbtGreen;
image[i][j].rgbtBlue = tempImage[i][j].rgbtBlue;
}
}
return;
}
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE temp[height][width];
int gx[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
int gy[3][3] = {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}};
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int gxBlue = 0;
int gyBlue = 0;
int gxGreen = 0;
int gyGreen = 0;
int gxRed = 0;
int gyRed = 0;
for (int r = -1; r < 2; r++) {
for (int c = -1; c < 2; c++) {
if (i + r < 0 || i + r > height - 1)
continue;
if (j + c < 0 || j + c > width - 1)
continue;
gxBlue += image[i + r][j + c].rgbtBlue * gx[r + 1][c + 1];
gyBlue += image[i + r][j + c].rgbtBlue * gy[r + 1][c + 1];
gxGreen += image[i + r][j + c].rgbtGreen * gx[r + 1][c + 1];
gyGreen += image[i + r][j + c].rgbtGreen * gy[r + 1][c + 1];
gxRed += image[i + r][j + c].rgbtRed * gx[r + 1][c + 1];
gyRed += image[i + r][j + c].rgbtRed * gy[r + 1][c + 1];
}
}
int blue = round(sqrt(gxBlue * gxBlue + gyBlue * gyBlue));
int green = round(sqrt(gxGreen * gxGreen + gyGreen * gyGreen));
int red = round(sqrt(gxRed * gxRed + gyRed * gyRed));
temp[i][j].rgbtBlue = (blue > 255) ? 255 : blue;
temp[i][j].rgbtGreen = (green > 255) ? 255 : green;
temp[i][j].rgbtRed = (red > 255) ? 255 : red;
}
}
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
image[i][j].rgbtBlue = temp[i][j].rgbtBlue;
image[i][j].rgbtGreen = temp[i][j].rgbtGreen;
image[i][j].rgbtRed = temp[i][j].rgbtRed;
}
}
return;
}
–
執行
Learn More →
驗證
Learn More →
記憶卡檔案用 hex editor 打開時,會看到的彩蛋 XD
Learn More →
style50
風格的程式碼#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
// must have argument (input file)
if (argc != 2)
{
printf("Usage: ./recover card.raw\n");
return 1;
}
// read file data
FILE *file = fopen(argv[1], "r");
// ensure file is valid
if (file == NULL)
{
printf("Could not open file");
return 2;
}
// initial variables
BYTE buffer[512];
FILE *img = NULL;
char filename[8];
int img_count = 0;
// read file, and store to buffer
while (fread(buffer, sizeof(char), 512, file))
{
// use bitwise operator check 4th bit is valid
// 0xe0 = 1110 0000
// 0xe1 = 1110 0001
// 0xe2 = 1110 0010
// 0xe3 = 1110 0011
// 0xe4 = 1110 0100
// 0xe5 = 1110 0101
// 0xe6 = 1110 0110
// 0xe7 = 1110 0111
// 0xe8 = 1110 1000
// 0xe9 = 1110 1001
// 0xea = 1110 1010
// 0xeb = 1110 1011
// 0xec = 1110 1100
// 0xed = 1110 1101
// 0xee = 1110 1110
// 0xef = 1110 1111
// & 0xf0 = 1111 0000
// when use & 0xf0, it means Upper part value will be change to 0xe0
bool valid_4th_bit = (buffer[3] & 0xf0) == 0xe0;
// if is a JPEG (start with 0xff 0xd8 0xff ...)
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && valid_4th_bit)
{
// fix memory leak issue
if (img_count > 0)
{
fclose(img);
}
// set value to filename (e.g. 000.jpg, 001.jpg, 002.jpg ...)
sprintf(filename, "%03i.jpg", img_count);
// create file for output
img = fopen(filename, "w");
img_count++;
}
// check img must be valid, then fwrite
if (img != NULL)
{
fwrite(buffer, sizeof(char), 512, img);
}
}
fclose(img);
fclose(file);
return 0;
}
–
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
// must have argument (input file)
if (argc != 2) {
printf("Usage: ./recover card.raw\n");
return 1;
}
// read file data
FILE *file = fopen(argv[1], "r");
// ensure file is valid
if (file == NULL) {
printf("Could not open file");
return 2;
}
// initial variables
BYTE buffer[512];
FILE *img = NULL;
char filename[8];
int img_count = 0;
// read file, and store to buffer
while (fread(buffer, sizeof(char), 512, file))
{
// use bitwise operator check 4th bit is valid
// 0xe0 = 1110 0000
// 0xe1 = 1110 0001
// 0xe2 = 1110 0010
// 0xe3 = 1110 0011
// 0xe4 = 1110 0100
// 0xe5 = 1110 0101
// 0xe6 = 1110 0110
// 0xe7 = 1110 0111
// 0xe8 = 1110 1000
// 0xe9 = 1110 1001
// 0xea = 1110 1010
// 0xeb = 1110 1011
// 0xec = 1110 1100
// 0xed = 1110 1101
// 0xee = 1110 1110
// 0xef = 1110 1111
// & 0xf0 = 1111 0000
// when use & 0xf0, it means Upper part value will be change to 0xe0
bool valid_4th_bit = (buffer[3] & 0xf0) == 0xe0;
// if is a JPEG (start with 0xff 0xd8 0xff ...)
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && valid_4th_bit) {
// fix memory leak issue
if (img_count > 0)
fclose(img);
// set value to filename (e.g. 000.jpg, 001.jpg, 002.jpg ...)
sprintf(filename, "%03i.jpg", img_count);
// create file for output
img = fopen(filename, "w");
img_count++;
}
// check img must be valid, then fwrite
if (img != NULL)
fwrite(buffer, sizeof(char), 512, img);
}
fclose(img);
fclose(file);
return 0;
}
–
執行
Learn More →
驗證
Learn More →
其實之前就已經修完 CS50 了,不過因應 2022 年將課堂作業的系統 從 c9.io 換到 github codespace + vscode 整合 打算來重溫一下裡面的作業,並暖身一下 C 語言的手感 由於已經有許多前輩分享課程與作業的心得 加上官網教材的投影片、重點筆記、教學影片都非常完整 故不再做詳細的紀錄,專注在作業 (Lab, Problem sets) 上面 https://cs50.harvard.edu/x/2022/weeks/7/
Oct 18, 2022其實之前就已經修完 CS50 了,不過因應 2022 年將課堂作業的系統 從 c9.io 換到 github codespace + vscode 整合 打算來重溫一下裡面的作業,並暖身一下 C 語言的手感 由於已經有許多前輩分享課程與作業的心得 加上官網教材的投影片、重點筆記、教學影片都非常完整 故不再做詳細的紀錄,專注在作業 (Lab, Problem sets) 上面 https://cs50.harvard.edu/x/2022/weeks/6/
Oct 18, 2022其實之前就已經修完 CS50 了,不過因應 2022 年將課堂作業的系統 從 c9.io 換到 github codespace + vscode 整合 打算來重溫一下裡面的作業,並暖身一下 C 語言的手感 由於已經有許多前輩分享課程與作業的心得 加上官網教材的投影片、重點筆記、教學影片都非常完整 故不再做詳細的紀錄,專注在作業 (Lab, Problem sets) 上面 https://cs50.harvard.edu/x/2022/weeks/5/
Oct 18, 2022其實之前就已經修完 CS50 了,不過因應 2022 年將課堂作業的系統 從 c9.io 換到 github codespace + vscode 整合 打算來重溫一下裡面的作業,並暖身一下 C 語言的手感 由於已經有許多前輩分享課程與作業的心得 加上官網教材的投影片、重點筆記、教學影片都非常完整 故不再做詳細的紀錄,專注在作業 (Lab, Problem sets) 上面 https://cs50.harvard.edu/x/2022/weeks/3/
Oct 18, 2022or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up