VS2013 中結構體輸入:輸入名字後程序直接結束,後續 `scanf_s` 全被跳過。Dev-C++ (GCC) 正常。
`scanf_s` 是 C11 可選安全函數,**`%s`/`%c` 格式必須提供緩衝區大小參數**;VS 強制要求,GCC 默認不強制。
// ❌ 錯誤:缺少大小參數
scanf_s("%s", &me.name);
scanf_s("%s", &me.sex);
// ✅ 正確:提供緩衝區大小(字符數,含結束符)
scanf_s("%s", &me.name, (unsigned)_countof(me.name)); // 10
scanf_s("%s", &me.sex, (unsigned)_countof(me.sex)); // 5
// 或手動指定
scanf_s("%s", me.name, 10);
scanf_s("%s", me.sex, 5);
| 格式符 | 額外參數 | 含義 |
|---|---|---|
| %s | 緩衝區大小 (rsize_t) | 最大讀入字符數(含\0) |
| %c | 緩衝區大小 | 通常為 1 |
| %[...] | 緩衝區大小 | 字符集匹配 |
| %d/%f/%p... | 無 | 非字符串類型無需大小 |
#include
#include
struct People {
char name[10];
char sex[5];
int age;
int Class;
};
int main() {
struct People me;
printf("Please Input Your Name\n");
// 注意:數組名即地址,無需 &,_countof 需 或手動計算
scanf_s("%9s", me.name, (unsigned)sizeof(me.name)); // %9s 防溢出,大小含\0
printf("Please Input Your Sex\n");
scanf_s("%4s", me.sex, (unsigned)sizeof(me.sex));
printf("Please Input Your Age\n");
scanf_s("%d", &me.age);
printf("Please Input Your Class\n");
scanf_s("%d", &me.Class);
printf("Name: %s\nSex: %s\nAge: %d\nClass: %d\n", me.name, me.sex, me.age, me.Class);
system("pause");
return 0;
}
// 宏適配:MSVC 用 scanf_s,GCC/Clang 用 scanf
#if defined(_MSC_VER)
#define MY_SCANF_S(fmt, ...) scanf_s(fmt, __VA_ARGS__)
#else
#define MY_SCANF_S(fmt, ...) scanf(fmt, __VA_ARGS__)
#endif
// 使用
MY_SCANF_S("%s", me.name, sizeof(me.name)); // GCC 忽略額外參數
#include
#include
#include
struct People {
std::string name;
std::string sex;
int age;
int Class;
};
int main() {
People me;
std::cout << "Name: "; std::getline(std::cin, me.name);
std::cout << "Sex: "; std::getline(std::cin, me.sex);
std::cout << "Age: "; std::cin >> me.age; std::cin.ignore(std::numeric_limits::max(), '\n');
std::cout << "Class: "; std::cin >> me.Class;
// ...
}
VS2013 強制執行 C11 `scanf_s` 緩衝區大小檢查。**`%s/%c` 必須加大小參數**,否則行為未定義(跳過輸入、崩潰、靜默截斷)。跨平台代碼請用宏適配,或直接用 C++ iostream 徹底避開 C 安全函數陷阱。