書籍
- C言語プログラミング ハーベイ M.ダイテル (著), ポール J.ダイテル (著), 小嶋 隆一 (翻訳)
- development environment
- Visual Stdio Code
- gcc 8.1.0
14.2: 可変長引数リストを使って関数productに渡された一連の整数の積を計算するプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
int product(int, ...);
int main()
{
printf("%d\n", product(2, 3, 5));
printf("%d\n", product(3, 5, 5, 5));
printf("%d\n", product(5, 1, 3, 4, 5, 5));
getch();
return 0;
}
int product(int i, ...)
{
int total = 1;
int j;
va_list ap;
va_start(ap, i);
for (j = 1; j <= i; j++)
{
total *= va_arg(ap, int);
}
va_end(ap);
return total;
}
14.3: プログラムのコマンド引数をプリントするプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
int i;
printf("コマンド行をプリントします\n");
for (i = 0; argv[i] != NULL; i++)
{
printf("%s\n", argv[i]);
}
getch();
return 0;
}
14.4: 整数型配列を昇順あるいは降順にソートするプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
void sortDecendArray(int [], int);
void sortAcentArray(int [], int);
void printArray(int [], int);
int main(int argc, char *argv[])
{
int array[10];
char option = '\0'; // ナル文字で初期化
int i;
void (*f[4])(int [], int);
f[0] = sortAcentArray;
f[3] = sortDecendArray;
// ソート前
printf("ソート前\n");
printArray(array, 10);
for (i = 0; argv[i] != NULL; i++)
{
if (*argv[i] == '-')
{
if (*(argv[i] + 1) == 'a')
{
option = 'a';
}
else if (*(argv[i] + 1) == 'd')
{
option = 'd';
}
}
}
// オプションフラグが立っているならば
if (option)
{
printf("%c", option);
// オプションに応じた関数を呼び出す
(*f[option - 'a'])(array, 10);
// ソート後
printf("ソート後\n");
printArray(array, 10);
}
getch();
return 0;
}
// 降順に配列をソート
void sortDecendArray(int a[], int size)
{
int position;
int count;
int tmp;
for (count = 1; count <= size - 1; count++)
{
for (position = 0; position <= size - 2; position++)
{
if (a[position] > a[position + 1])
{
tmp = a[position];
a[position] = a[position + 1];
a[position + 1] = tmp;
}
}
}
}
void sortAcentArray(int a[], int size)
{
int position;
int count;
int tmp;
for (count = 1; count <= size - 1; count++)
{
for (position = 0; position <= size - 2; position++)
{
if (a[position] < a[position + 1])
{
tmp = a[position];
a[position] = a[position + 1];
a[position + 1] = tmp;
}
}
}
}
void printArray(int a[], int size)
{
int i;
for (i = 0; i < size; i++)
{
printf("%d\n", a[i]);
}
}
14.5: ファイル内の各文字のあいだにスペースを入れるプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
void fileCopy(FILE *, FILE *);
int main(int argc, char *argv[])
{
char c;
FILE *source;
FILE *tmp;
if (argv[1] == NULL)
{
fprintf(stderr, "ファイル名が指定されていません\n");
return -1;
}
if ((source = fopen(argv[1], "r+")) == NULL)
{
fprintf(stderr, "%sが開けませんでした\n", argv[1]);
return -1;
}
if ((tmp = fopen ("tmp.txt", "w+")) == NULL)
{
fprintf(stderr, "tmp.txtの生成に失敗しました\n");
return -1;
}
while ((c = fgetc(source)) != EOF)
{
// 文字を一時ファイルに出力
fputc(c, tmp);
// 各文字の間にスペースを入れる
fputc(' ', tmp);
}
// ファイル位置ポインタを先頭に戻す
rewind(source);
rewind(tmp);
// ファイルをコピーする
fileCopy(tmp, source);
// ファイルクローズ
fclose(tmp);
fclose(source);
getch();
return 0;
}
void fileCopy(FILE *from, FILE *to)
{
char c;
while ((c = fgetc(from)) != EOF)
{
putc(c, to);
}
}
14.6: シグナル関数を実装したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
void signalHandler(void);
void signalHandler1(void);
int main()
{
signal(SIGINT, signalHandler);
signal(SIGABRT, signalHandler1);
// わざと中断
abort();
// ループの中でSIGINT割り込みを起こす
while(1);
getch();
return 0;
}
void signalHandler(void)
{
printf("SIGINTが補足されました\n");
}
void signalHandler1(void)
{
printf("SIGABRTが補足されました\n");
}
14.7: 整数の配列を動的に確保するプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
void inputArray(int [], int);
void printArray(int [], int);
int main()
{
int size;
int *arrayPtr;
// srand(time(NULL));
printf("配列のサイズを入力してください\n");
scanf("%d", &size);
if ((arrayPtr = (int *)malloc(size)) == NULL)
{
fprintf(stderr, "配列を確保することができませんでした\n");
return -1;
}
// 配列に値を入力
inputArray(arrayPtr, size);
// 配列に格納された値を表示
printArray(arrayPtr, size);
printf("配列を再確保します\n");
if ((arrayPtr = (int *)realloc(arrayPtr, size / 2)) == NULL)
{
fprintf(stderr, "配列の再確保に失敗しました\n");
return -1;
}
// 配列に格納された値を表示
printArray(arrayPtr, size / 2);
getch();
return 0;
}
void inputArray(int a[], int size)
{
int i;
printf("配列に値を入れます\n");
for (i = 0; i < size; i++)
{
a[i] = rand() % RAND_MAX;
}
}
void printArray(int a[], int size)
{
int i;
for (i = 0; i < size; i++)
{
printf("%d\n", a[i]);
}
}
14.8: コマンドライン引数により指定したファイルの内容を、逆さに別の指定したファイルに書き込むプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#define FILE_SIZE 10000
int main(int argc, char *argv[])
{
FILE *readPtr;
FILE *writePtr;
char fileBuf[FILE_SIZE];
char c;
int i;
int endFlag = 0; // エンドフラグ
// ファイルが指定されてないならばエラー表示を表示して終了
if (argv[1] == NULL || argv[2] == NULL)
{
fprintf(stderr, "ファイル名が指定されていません\n");
return -1;
}
// ファイル1がオープンできないならばエラーを表示して終了
if ((readPtr = fopen(argv[1], "r+")) == NULL)
{
fprintf(stderr, "ファイル1をオープンできませんでした\n");
return -1;
}
// ファイル2がオープンできないならばエラーを表示して終了
if ((writePtr = fopen(argv[2], "w")) == NULL)
{
fprintf(stderr, "ファイル2をオープンできませんでした\n");
return -1;
}
// ファイルサイズより少なく,エンドフラグが立ってないならばループ
for (i = 0; i < FILE_SIZE && endFlag == 0; i++)
{
// EOFでないならばファイルバッファにファイルデータを格納
if ((c = fgetc(readPtr)) != EOF)
{
fileBuf[i] = c;
}
// EOFならばエンドフラグを立ててループを抜ける
else
{
endFlag= 1;
}
}
// 読み込まれたファイルデータ逆さに書き出す
for (; (i - 1) >= 0; i--)
{
fputc(fileBuf[i], writePtr);
}
getch();
return 0;
}
14.9: goto文にてfor文を表現するプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
int main()
{
int i = 0;
int j = 0;
PRINT1: printf("*");
printf("*");
printf("*");
printf("*");
printf("*");
printf("\n");
i++;
if (i >= 2)
{
goto END;
}
else if(i == 1)
{
goto PRINT2;
}
PRINT2: printf("*");
printf(" ");
printf(" ");
printf(" ");
printf("*");
printf("\n");
j++;
if (j <3)
{
goto PRINT2;
}
else
{
goto PRINT1;
}
END:
getch();
return 0;
}
