1. 使用 printf 和 std::cout 输出指定内容
#
#include <cstdio>
#include <iostream>
int main() {
const char stuff1[] = "eggplant";
const char stuff2[] = "tomato";
const char donation1[] = "my NUTRIENTS";
const char donation2[] = "ANTIOXIDANTS";
// 使用printf输出第一行
printf("If I'm an %s Then I will give you %s\n", stuff1, donation1);
// 使用std::cout输出第二行
std::cout << "If I'm a " << stuff2 << " Then I will give you " << donation2 << std::endl;
return 0;
}
2. 使用 C 和 C++实现数字输入和加法运算 #
C 版本:
#include <cstdio>
int main() {
int a, b;
printf("请输入两个数字,用空格分隔:");
scanf("%d %d", &a, &b);
printf("%d + %d = %d\n", a, b, a + b);
return 0;
}
C++版本:
#include <iostream>
int main() {
int a, b;
std::cout << "请输入两个数字,用空格分隔:";
std::cin >> a >> b;
std::cout << a << " + " << b << " = " << a + b << std::endl;
return 0;
}
3. 使用 C++版本处理中文数字输入 #
当输入 “十五 十二” 时,程序会出现问题,因为 std::cin 无法直接将中文数字转换为整数。程序会尝试读取但失败,变量 a 和 b 将保持未初始化状态或默认值,输出结果可能是类似 0 + 0 = 0 或 114514 + 1919810 = 2063324 这样的无意义(?)结果。
4.添加了调试代码 #
#include <cstdio>
int main() {
int a, b;
printf("请输入两个数字,用空格分隔:");
int count = scanf("%d %d", &a, &b);
printf("%d + %d = %d\n", a, b, a + b);
printf("成功读入了%d个参数\n", count);
char remain[100] = "";
if(count < 2) {
fgets(remain, 100, stdin);
printf("缓冲区还剩下:%s", remain);
}
return 0;
}
测试结果分析:
-
正常输入阿拉伯数字(如 “15 12”):
- 输出:
15 + 12 = 27 count值为 2,表示成功读取了两个参数- 不会进入 if 语句块,不会显示缓冲区剩余内容
- 输出:
-
输入 “15 十二”:
- 输出:
15 + 114514 = 114529(第二个数字可能是随机值) count值为 1,表示只成功读取了一个参数- 会进入 if 语句块,显示缓冲区还剩下:" 十二"
- 输出:
-
输入 “十五 十二”:
-
输出:
114514 + 1919810 = 2063324(两个数字都是随机值) -
count值为 0,表示没有成功读取任何参数 -
会进入 if 语句块,显示缓冲区还剩下:“十五 十二”
-
启示与解决思路 #
说白了,这堆问题核心就一件事:C 和 C++里那些输入函数(scanf 和 std::cin)都挺娇气的,你喂它吃错东西——比如该吃数字你喂它中文——它就撂挑子了。
scanf 的返回值代表它成功得到了几个 % 参数,比如 int count = scanf("%d %d", &a, &b); 里面预期就该返回 2。剩下的数据会留在输入缓冲区里面,剩给下一次输入;而这往往会破坏下一次输入,就像 DNA 插入了一个碱基对那样:
#include <stdio.h>
int main() {
int id = 0;
char name[100] = "";
printf("输入你的学号\n");
scanf("%d", &id);
printf("输入你的姓名\n");
scanf("%s", name);
printf("你好,%s,你的学号是%d", name, id);
return 0;
}
交互:
输入你的学号
213ab
输入你的姓名
你好,ab,你的学号是213
这就是因为多余的 ab 剩在了输入缓冲区,导致下一个输入直接拿走了 'ab\n' (当然,\n 丢弃了),用户无法输入。
而 std::cin 就更闷葫芦一点,它只会设置一个标志位 std::cin.fail(),然后开始傲娇,拒绝继续读入(涉及基于 iostream 的所有输入方式,包括 std::cin 本身、还有 getline 等等)。
对于 scanf,判断输入是否有误的方式就是检查返回值是不是 % 参数的个数。另外,如果输入有误,因为有 黏糊糊的“脏数据”留在输入缓冲区里了,所以得自己想办法 事后 清理干净。
对于 std::cin,就需要检查 std::cin.fail() 是不是 true,如果它果然开始傲娇了,你就该 带 TA 去咖啡馆摸摸头 告诉 TA 没事了(cin.clear()),然后把剩下的清理掉,这个 std::cin 自己有方法,就是 cin.ignore()。然后就一切如常了。
至于为什么输入 十二 十五 会引发错误,就更简单了,对于 scanf 和 std::cin,它们只接受阿拉伯数字,十二 十五 对它们来说只是普通的字符串,当然不能被 %d 识别了。如果你硬要处理汉字,那压力就到你身上了——你得自己写解析。所以这种情况最好的方式就是直接报错,告诉用户该怎么输入。毕竟可能的错误输入是无穷的,而合理的就那么一两个。
目前,由于还没有学习控制语句和更多 IO 技术,可以先了解这些基本思路,后续学习你会知道具体如何实现的。
5. 日记本 #
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::ifstream inputFile("diary.txt");
// 检查文件是否成功打开
if (!inputFile.is_open()) {
std::cerr << "Unable to open diary.txt." << std::endl;
std::cerr << "Please make sure it exists." << std::endl;
return 1;
}
std::ofstream outputFile("decrypted_diary.txt");
// 检查输出文件是否成功创建
if (!outputFile.is_open()) {
std::cerr << "Unable to create decrypted_diary.txt" << std::endl;
inputFile.close();
return 1;
}
char ch;
std::string decryptedContent;
// 读取每个字符并解密
while (inputFile.get(ch)) {
// 将ASCII码减1
char decryptedChar = ch - 1;
outputFile << decryptedChar;
decryptedContent += decryptedChar;
}
// 关闭文件
inputFile.close();
outputFile.close();
// 在控制台显示解密结果
std::cout << "decrypted!" << std::endl;
std::cout << "origin: cbojttzvnnfooup.ezjtv.xp.svep" << std::endl;
std::cout << "decrypted: " << decryptedContent << std::endl;
std::cout << "saved to decrypted_diary.txt" << std::endl;
return 0;
}
或者C版本,逻辑稍有不同:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *inputFile = fopen("diary.txt", "r");
FILE *outputFile = fopen("decrypted_diary.txt", "w");
if (inputFile == NULL) {
printf("Unable to open diary.txt.\n");
printf("Please make sure it exists.\n");
return 1;
}
if (outputFile == NULL) {
printf("Unable to create decrypted_diary.txt\n");
fclose(inputFile);
return 1;
}
int ch;
printf("decrypted!\n");
printf("origin: cbojttzvnnfooup.ezjtv.xp.svep\n");
printf("decrypted: ");
// 读取每个字符并解密
while ((ch = fgetc(inputFile)) != EOF) {
char decryptedChar = ch - 1;
fputc(decryptedChar, outputFile);
putchar(decryptedChar);
}
printf("\nsaved to decrypted_diary.txt\n");
fclose(inputFile);
fclose(outputFile);
return 0;
}