文章目录
- 版本1(简略版)
- v1 效果
- 版本2:详解输入输出和流缓冲区版
- 输出结果
- 版本3:进一步改进
- fflush/getchar()清空输入缓冲区
- 测试用例和结果
版本1(简略版)
/*sizeof()运算符是有局限性的,在于它不是动态的
C/C++中,sizeof()只是运算符号,是编译的时候确定大小的。动态分配是运行过程中得到大小的,也就是说C++中new出来的内存,sizeof都无法统计的,
退一步说,即使是new出来的空间也有可能失败,所以sizeof无法统计动态分配的内存大小。*/
int main() {
void myBubbleSort(int *num_array, int size);
while (1) {
int num_array[1000];
printf("input numbers you want to sort(bubble sort):\n");
/*read in integers without size indicate:*/
char c;//to temporary save a charactor to judge the '\n'
int size = 0;
//int isEof = 0;
while ((c = getchar()) != '\n') {
/*return the charater which is not '\n'*/
ungetc(c, stdin);
/*now read in the integer number:
use the scanf("%d",&num_array[i]) to save the number to array*/
isEof = scanf("%d", &num_array[size++]);
}
//size= sizeof(num_array) / sizeof(int);
/*invoke the sort function:*/
myBubbleSort(num_array, size);
/*print the sorted sequence consequence*/
for (int i = 0; i < size; i++) {
printf("%d ", num_array[i]);
}
printf("\n");
}
}
/*the bubble sort function:*/
void myBubbleSort(int *num_array, int size) {
void swap(int *a, int *b);
/*we need two for loop*/
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - 1 - i; j++) {
if (*(num_array + j) > *(num_array + j + 1)) {
swap(num_array + j, num_array + j + 1);
}
}
}
}
void swap(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
/*
test data
5 3 7 1 9 33 66 44 333 11
9 33 66 7 1 9 33 44 34733 11
3 6 0 2 5
*/
v1 效果
版本2:详解输入输出和流缓冲区版
#include <stdio.h>
// 数值调试宏
#ifndef CXXU
#define CXXU 1
#define dprint(expr) printf(#expr " = %d\n", expr)
#define gprint(expr) printf(#expr " = %g\n", expr)
#define fprint(expr) printf(#expr " = %f\n", expr)
#define sprint(expr) printf(#expr " = %s\n", expr)
#define cprint(expr) printf(#expr " = %c\n", expr)
#define sprintln(expr) printf(expr "\n")
// 直接传递变量给pprint(取地址操作包含在了宏中)
#define pprint(expr) printf(#expr " = %p\n", &expr)
#endif
/*sizeof()运算符是有局限性的,在于它不是动态的*/
int main()
{
void myBubbleSort(int *num_array, int size);
/* 将以下代码放在一个不停止的循环中,以便于用户连续测试多组输入 */
int round = 1;
int readed_counter = 0;
while (1)
{
int num_array[1000];
printf("input numbers you want to sort(bubble sort):\n");
/*read in integers without size indicate:*/
char c; // to temporary save a charactor to judge the '\n'
int size = 0;
/* getchar():Read a character from stdin.
*/
/* 下面的逻辑段满足以下需求:
将输入流中的字符视为整数读入,不同的整数用空格符分割
遇到回车时,结束本轮输入,(注意,不是通过EOF信号来结束一组(一行)测试输入,而是通过回车键来结束本组数据的读取(离开读取循环))
并且将已经读取的不定长度的整数序列交给排序函数进行排序
读取整数的过程中,一并累计读入的整数数目(size++实现) */
/* 实现细节:
为了能够做到,当输入回车时,就结束本组测试数据的输入,(而不是通过文件末尾/ctrl+z/ctrl+d来结束),我们使用
getchar()&ungetc()组合,来检测输入流中的回车符,同时维持输入流中的内容和getchar()读走一个字符前后一致,
这样我们后面使用scanf将输入流中的数字字符&空格序列以正确的方式解析为整数读取提供保障 */
while ((c = getchar()) != '\n')
{
/*return the charater to stdin which is not '\n'*/
/* Push a character back onto the input buffer of STREAM.
*/
// cprint(c);
dprint(c);
/* ungetc() pushes c back to stream, cast to unsigned char, where it is available for subsequent read operations. Pushed-back characters will be returned in reverse order; only one pushback is guaranteed.
Calls to the functions described here can be mixed with each other and with calls to other input functions from the stdio library for the same input stream. */
int back = ungetc(c, stdin);
dprint(back);
/*now read in the integer number:
use the scanf("%d",&num_array[i]) to save the number to array*/
/*
scanf
RETURN VALUE
On success, these functions return the number of input items successfully matched
and assigned; this can be fewer than provided for, or even zero, in the event of
an early matching failure.
The value EOF is returned if the end of input is reached before either the first
successful conversion or a matching failure occurs. EOF is also returned if a
read error occurs, in which case the error indicator for the stream (see fer‐
ror(3)) is set, and errno is set to indicate the error. */
/* 简单的说,就是scanf通过读取输入流中的内容,将其解析为整数
无论是getchar()还是scanf(),他们读取同一个输入流缓冲区,被读取走的字符就没有了
除非用ungetc()将指定内容填补输入流,而且还是添补在前面,以便下一次被读取,上面的判断就是依靠ungetc()来维持缓冲区中的内容,使得scanf不知道输入流经历了怎样的变化,仿佛是直接从键盘上读取序列一样
scanf函数会消耗遇到输入流中的空白符时,因为这里的scanf格式串中要匹配的是有符号十进制整数,所以只消耗十进制数(whites pace字符此时不属于被消耗对象)!
如果将前面的操作视为整体,那么使得输入流内容减少的就是下面的scanf()
如果您运行程序,将会发现,除了第一个字符意外,其余的c=9/32(制表符或者空格的ascii)*/
readed_counter = scanf("%d", &num_array[size++]);
// dprint(readed_counter);
}
printf("end while:");
dprint(round);
// size= sizeof(num_array) / sizeof(int);
/*invoke the sort function:*/
myBubbleSort(num_array, size);
printf("the sort result,test data round: %d\n",round);
/*print the sorted sequence consequence*/
for (int i = 0; i < size; i++)
{
printf("%d ", num_array[i]);
}
printf("\n");
}
}
/*the bubble sort function:*/
void myBubbleSort(int *num_array, int size)
{
void swap(int *a, int *b);
/*we need two for loop*/
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - 1 - i; j++)
{
if (*(num_array + j) > *(num_array + j + 1))
{
swap(num_array + j, num_array + j + 1);
}
}
}
}
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
/*
test data
5 3 7 1 9 33 66 44 333 11
9 33 66 7 1 9 33 44 34733 11
3 6 0 2 5
*/
输出结果
$ ./sorter
input numbers you want to sort(bubble sort):
0 3 -55 7 1
c = 48
back = 48
c = 32
back = 32
c = 32
back = 32
c = 32
back = 32
c = 32
back = 32
end while:round = 1
the sort result,test data round: 1
-55 0 1 3 7
input numbers you want to sort(bubble sort):
版本3:进一步改进
打印出scanf读入的整数
每次预读取输入流中的两个字符来更好的查看getchar()和ungetc()是怎么配合工作的
fflush/getchar()清空输入缓冲区
-
while (getchar() != '\n');
- 或者直接:
fflush(stdin));
// 数值调试宏
// 直接传递变量给pprint(取地址操作包含在了宏中)
// extern void func();
// extern int multiply(int a, int b);
// extern char *str_multiplier;
/*sizeof()运算符是有局限性的,在于它不是动态的
C/C++中,sizeof()只是运算符号,是编译的时候确定大小的。动态分配是运行过程中得到大小的,也就是说C++中new出来的内存,sizeof都无法统计的,退一步说,即使是new出来的空间也有可能失败,所以sizeof无法统计动态分配的内存大小。*/
int main()
{
void myBubbleSort(int *num_array, int size);
/* 将以下代码放在一个不停止的循环中,以便于用户连续测试多组输入 */
int round = 1;
int readed_counter = 0;
while (1)
{
int num_array[1000];
printf("input numbers you want to sort(bubble sort):\n");
/*read in integers without size indicate:*/
char c; // to temporary save a charactor to judge the '\n'
int size = 0;
/* getchar():Read a character from stdin.
*/
/* 下面的逻辑段满足以下需求:
将输入流中的字符视为整数读入,不同的整数用空格符分割
遇到回车时,结束本轮输入,(注意,不是通过EOF信号来结束一组(一行)测试输入,而是通过回车键来结束本组数据的读取(离开读取循环))
并且将已经读取的不定长度的整数序列交给排序函数进行排序
读取整数的过程中,一并累计读入的整数数目(size++实现) */
/* 实现细节:
为了能够做到,当输入回车时,就结束本组测试数据的输入,(而不是通过文件末尾/ctrl+z/ctrl+d来结束),我们使用
getchar()&ungetc()组合,来检测输入流中的回车符,同时维持输入流中的内容和getchar()读走一个字符前后一致,
这样我们后面使用scanf将输入流中的数字字符&空格序列以正确的方式解析为整数读取提供保障 */
while ((c = getchar()) != '\n')
{
/*return the charater to stdin which is not '\n'*/
/* Push a character back onto the input buffer of STREAM.
*/
// cprint(c);
dprint(c);
/* ungetc() pushes c back to stream, cast to unsigned char, where it is available for subsequent read operations. Pushed-back characters will be returned in reverse order; only one pushback is guaranteed.
Calls to the functions described here can be mixed with each other and with calls to other input functions from the stdio library for the same input stream. */
/* 多读取几个看看 */
int c2 = getchar();
dprint(c2);
/* 统一打回,注意逆序!,这样才是正确的还原之前若干次getchar()所读掉的字符! */
int back2 = ungetc(c2, stdin);
dprint(back2);
int back = ungetc(c, stdin);
dprint(back);
/*now read in the integer number:
use the scanf("%d",&num_array[i]) to save the number to array*/
/*
scanf
RETURN VALUE
On success, these functions return the number of input items successfully matched
and assigned; this can be fewer than provided for, or even zero, in the event of
an early matching failure.
The value EOF is returned if the end of input is reached before either the first
successful conversion or a matching failure occurs. EOF is also returned if a
read error occurs, in which case the error indicator for the stream (see fer‐
ror(3)) is set, and errno is set to indicate the error. */
/* 简单的说,就是scanf通过读取输入流中的内容,将其解析为整数
无论是getchar()还是scanf(),他们读取同一个输入流缓冲区,被读取走的字符就没有了
除非用ungetc()将指定内容填补输入流,而且还是添补在前面,以便下一次被读取,上面的判断就是依靠ungetc()来维持缓冲区中的内容,使得scanf不知道输入流经历了怎样的变化,仿佛是直接从键盘上读取序列一样
scanf函数会`消耗`掉所有的空白字符,直到读取到格式控制串中所指导的数据类型(这里是十进制有符号整数,被匹配的整数整体后面的空白符被保留在缓冲区);
即,遇到输入流中的空白符会被丢弃,(因为这里的scanf格式串中要匹配的是有符号十进制整数),所以只消耗输入流中首次出现十进制数的地方(包括这个n位整数所占的这n(+1)位为止,
而之后的(whites pace字符不被消耗)!
如果将前面的操作视为整体,那么使得输入流内容减少的就是下面的scanf()
如果您运行程序,将会发现,除了第一个字符意外,其余的c=9/32(制表符或者空格的ascii)*/
readed_counter = scanf("%d", &num_array[size]);
// dprint(readed_counter);
dprint(num_array[size]);
size++;
}
// 清空输入流中的空白符残留(上述scanf的分析中提到了相关问题)
fflush(stdin);
printf("end while:");
dprint(round);
// size= sizeof(num_array) / sizeof(int);
/*invoke the sort function:*/
myBubbleSort(num_array, size);
printf("the sort result,test data round: %d\n", round);
/*print the sorted sequence consequence*/
for (int i = 0; i < size; i++)
{
printf("%d ", num_array[i]);
}
printf("\n");
}
}
/*the bubble sort function:*/
void myBubbleSort(int *num_array, int size)
{
void swap(int *a, int *b);
/*we need two for loop*/
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - 1 - i; j++)
{
if (*(num_array + j) > *(num_array + j + 1))
{
swap(num_array + j, num_array + j + 1);
}
}
}
}
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
测试用例和结果
- 下面包含三组不规则的测试数据(分隔符包括若干空格和若干制表符,都是空白符/混用)
/* 测试数据以及相应结果 */
/*
# cxxu @ cxxuAli in ~/cppCodes on git:master x [21:28:19]
$ ./sorter
input numbers you want to sort(bubble sort):
5 9 0 1
c = 53
c2 = 32
back2 = 32
back = 53
num_array[size] = 5
c = 32
c2 = 57
back2 = 57
back = 32
num_array[size] = 9
c = 32
c2 = 48
back2 = 48
back = 32
num_array[size] = 0
c = 32
c2 = 49
back2 = 49
back = 32
num_array[size] = 1
end while:round = 1
the sort result,test data round: 1
0 1 5 9
input numbers you want to sort(bubble sort):
3 2 8 0
c = 51
c2 = 32
back2 = 32
back = 51
num_array[size] = 3
c = 32
c2 = 32
back2 = 32
back = 32
num_array[size] = 2
c = 32
c2 = 32
back2 = 32
back = 32
num_array[size] = 8
c = 32
c2 = 48
back2 = 48
back = 32
num_array[size] = 0
end while:round = 1
the sort result,test data round: 1
0 2 3 8
input numbers you want to sort(bubble sort):
8 -1 0 99
c = 56
c2 = 32
back2 = 32
back = 56
num_array[size] = 8
c = 32
c2 = 32
back2 = 32
back = 32
num_array[size] = -1
c = 32
c2 = 9
back2 = 9
back = 32
num_array[size] = 0
c = 32
c2 = 57
back2 = 57
back = 32
num_array[size] = 99
end while:round = 1
the sort result,test data round: 1
-1 0 8 99
input numbers you want to sort(bubble sort):
*/