2024-2025 20241312计算机基础与程序设计》第十二周学习总结
学期(如2024-2025-1) 学号(:20241312) 《计算机基础与程序设计》第十二周学习总结
作业信息
这个作业属于哪个课程 | <班级的链接>(如2024-2025-1-计算机基础与程序设计) |
---|---|
这个作业要求在哪里 | <作业要求的链接>(如2024-2025-1计算机基础与程序设计第十二周作业) |
这个作业的目标 | 加入云班课,参考本周学习资源 |
自学教材
《C语言程序设计》第11章并完成云班课测试
|
|作业正文|https://www.cnblogs.com/songjialinsjl/p/18604699|
在C语言中,与文件操作有关的函数主要包含在 stdio.h
和 stdlib.h
头文件中。以下是一些常用的文件操作函数:
教材学习内容总结
标准 I/O 函数(stdio.h)
ai的学习
在读取整数后,使用 while (getchar() != '\n'); 清除 scanf 留下的换行符。不清除会怎么样
如果在读取整数后不清除 scanf
留下的换行符,接下来的 gets
或 fgets
调用可能会立即读取这个换行符,导致以下几个问题:
-
跳过输入:
gets
或fgets
会认为已经读到了一行的结尾(因为换行符\n
被当作行结束的标志),因此可能会跳过用户的实际输入,导致读取到空字符串。
-
不正确的输入处理:
- 如果
fgets
读到换行符,它会停止读取并返回,即使用户还没有输入任何其他字符。这意味着用户的名字或输入可能会被遗漏。
- 如果
-
程序逻辑错误:
- 程序可能逻辑上期望用户在每次提示后输入数据,但由于换行符的存在,程序可能会错误地认为用户已经输入了数据。
-
用户体验问题:
- 用户可能会感到困惑,因为他们输入的数据没有被正确处理或显示。
-
安全风险:
- 使用
gets
函数本身就有安全风险,因为它不检查目标缓冲区的大小,可能会导致缓冲区溢出。即使清除了换行符,使用gets
仍然是不安全的。
- 使用
示例说明
假设有以下代码片段:
#include <stdio.h>
int main() {
int n;
char name[40];
printf("Enter a number: ");
scanf("%d", &n); // 读取整数
printf("Enter your name: ");
fgets(name, sizeof(name), stdin); // 读取名字
printf("You entered: %s\n", name); // 打印名字
return 0;
}
如果用户输入 5
然后按下回车,scanf
会读取整数 5
,但留下换行符。接着 fgets
会立即读取这个换行符,认为已经读到了一行的结尾,因此 name
可能被赋值为空字符串。
为了避免这个问题,通常在 scanf
后使用以下代码清除换行符:
while (getchar() != '
那scanf/%c要不要读取换行符?
当使用 `scanf` 与 `%c` 格式说明符时,是否读取换行符取决于你的具体需求。`%c` 格式说明符用于读取单个字符,包括空格和换行符在内的任何字符。
### 读取换行符
如果你的目的是读取用户输入的每一个字符,包括换行符,那么你可以这样做:
```c
#include <stdio.h>
int main() {
char ch;
printf("Enter a character (including newline): ");
scanf("%c", &ch);
printf("You entered: %c\n", ch);
return 0;
}
在这个例子中,如果用户输入一个字符后按下回车键,scanf
会读取用户输入的字符以及换行符,并将其存储在变量 ch
中。
不读取换行符
如果你不希望读取换行符,而是希望忽略它,可以在 %c
前面加一个空格,这样 scanf
会跳过任何前导空白字符(包括换行符):
#include <stdio.h>
int main() {
char ch;
printf("Enter a character (ignoring newline): ");
scanf(" %c", &ch); // 注意 %c 前面的空格
printf("You entered: %c\n", ch);
return 0;
}
在这个例子中,scanf
会忽略用户输入前的任何空白字符,包括换行符。这样,即使用户在输入字符前按下了回车键,scanf
也会从下一个非空白字符开始读取。
总结
- 如果你需要处理包括换行符在内的每个字符,就不要在
%c
前加空格。 - 如果你希望忽略换行符和其他空白字符,就在
%c
前加一个空格。
根据你的具体需求选择合适的方法。在处理用户输入时,通常需要仔细考虑如何处理空白字符,以确保程序的行为符合预期。
-
打开文件:
fopen
:打开文件,返回一个FILE*
指针。FILE *fopen(const char *filename, const char *mode);
freopen
:重新打开文件,用于重定向标准输入输出。FILE *freopen(const char *filename, const char *mode, FILE *stream);
-
关闭文件:
fclose
:关闭文件。int fclose(FILE *stream);
-
读取文件:
fgetc
、getc
、getchar
:读取一个字符。int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void);
fgets
:读取一行。char *fgets(char *str, int num, FILE *stream);
fread
:读取多个元素。size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
-
写入文件:
fputc
、putc
、putchar
:写入一个字符。int fputc(int c, FILE *stream); int putc(int c, FILE *stream); int putchar(int c);
fputs
:写入一行。int fputs(const char *str, FILE *stream);
fwrite
:写入多个元素。size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
-
文件定位:
rewind
:重置文件位置到文件开始。void rewind(FILE *stream);
fseek
:移动文件位置。int fseek(FILE *stream, long offset, int whence);
ftell
:获取当前文件位置。long ftell(FILE *stream);
-
文件错误处理:
ferror
:检查文件错误。int ferror(FILE *stream);
clearerr
:清除文件错误和 EOF 标志。void clearerr(FILE *stream);
-
文件结束检测:
feof
:检查是否到达文件末尾。int feof(FILE *stream);
-
临时文件:
tmpfile
:创建临时文件。FILE *tmpfile(void);
tmpnam
:生成临时文件名。char *tmpnam(char *str);
其他文件操作函数(stdlib.h)
-
删除文件:
remove
:删除文件。int remove(const char *filename);
-
重命名文件:
rename
:重命名文件。int rename(const char *oldname, const char *newname);
这些函数提供了基本的文件操作功能,包括打开、关闭、读取、写入、定位和删除文件。在使用这些函数时,需要正确处理文件指针,并在必要时检查返回值以确保操作成功。