C言語初心者です。
メモ
ソース整形
clang-format -style webkit a.c
- 「'」で囲まれた文字は文字リテラル。1文字を表すためだけに利用できる。
- 「"」で囲まれた文字はアドレスを表す。文字列の後には「NULL」が付け加えられる。
文字列
#include <stdio.h>
int main() {
char *p = "にほんご";
printf("%s", p);
char q[] = "にほんご";
printf("%s", q); // 表示されない
}
- string.h は strcmp に必要
文字列
#include <stdio.h>
#include <string.h>
int main()
{
char* p = "にほんご1";
if (p == "にほんご1") {
printf("%s", p);
}
char q[] = "にほんご2";
if (strcmp(q, "にほんご2") == 0) {
printf("%s", q);
}
}
ハマったところ
文字列の直接比較ができない
- 文字列比較するためには
string.h
のstrcmp()
を使う必要がある。 - strcmpは
一致する場合0を返す
ので、if文でstrcmp(env,"x86")==0
とする必要があった。 - 自作関数
detect_arch
から戻すときにchar
ではなくchar*
で戻す必要がある(?) -
switch(文字列)
と書くことができない。
Wow64を考慮していないコード
-
getenv("PROCESSOR_ARCHITECTURE")
がAMD64でもx86
を返す。- (
cmd /k "echo % PROCESSOR_ARCHITECTURE%"
ではAMD64を返す。) - 恐らく64bit OSでも32bit OSとしてexeを実行するため(?)
- 解答見つけました。WOW64 実装の詳細 (Windows)
- (
detect_arch_then_exec_uac.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *detect_arch(void);
int main(void) {
printf("%s", detect_arch());
system("UserAccountControlSettings.exe");
return 0;
}
char *detect_arch(void) {
char *env;
char *arch;
env = getenv("PROCESSOR_ARCHITECTURE");
if (strcmp(env,"x86")==0) {
arch = "32 bit";
} else if (strcmp(env,"AMD64")==0) {
arch = "64 bit";
} else {
arch = "unknown arch.";
}
return arch;
}
動くコード
-
ProgramW6432
が存在するかで判断してます。
#include <stdio.h>
#include <stdlib.h>
const char *detect_arch(void);
int main(void) {
printf("%s", detect_arch());
system("UserAccountControlSettings.exe");
return 0;
}
const char *detect_arch(void) {
const char *arch;
if (getenv("ProgramW6432")) {
arch = "64 bit";
} else {
arch = "32 bit";
}
return arch;
}