gets
函数 -
fgets
函数 -
scanf
函数 -
gets_s
函数 - 字符串最后一个单词的长度
gets
函数 -
fgets
函数 -
scanf
函数 -
gets_s
函数 - 字符串最后一个单词的长度
1. gets
函数
在 C 语言中,while
循环的功能和它在其他语言中一样。它首先测试表达式的值,如果是假的 (0
) 就跳过循环体。如果表达式的值是真的 (非 0
),就执行循环体内的代码,然后再重新测试表达式的值。
这个循环代表了这个程序的主要逻辑。简而言之,它表示:
while 我们还可以读取另一行输入时
打印输入行
对输入行进行重新整理,把它存储于 output 数组
打印输出结果
gets
函数从标准输入读取一行文本并把它存储于作为参数传递给它的数组中。一行输入由一串字符组成,以一个换行符 (newline) 结尾。gets
函数丢弃换行符,并在该行的末尾存储一个 NUL
字节 (一个 NUL
字节是指字节模式为全 0 的字节,类似 '\0'
这样的字符常量)。然后,gets
函数返回一个非 NULL
值,表示该行己被成功读取。当 gets
函数被调用但事实上不存在输入行时,它就返回 NULL
值,表示它到达了输入的末尾 (文件尾)。
在 C 程序中,处理字符串是常见的任务之二。尽管 C 语言并不存在 string
数据类型,但在整个语言中,存在一项约定:字符串就是一串以 NUL
字节结尾的字符。NUL
是作为字符串终止符,它本身并不被看作是字符串的一部分。字符串常量 (string literal) 就是源程序中被双引号括起来的一串字符。例如,字符串常量:
“Hello”
在内存中占据 6 个字节的空间,按顺序分别是 H
、e
、l
、l
、o
和 NUL
。
printf
函数执行格式化的输出。C 语言的格式化输出比较简单,printf
函数接受多个参数,其中第一个参数是一个字符串,描述输出的格式,剩余的参数就是需要打印的值。格式常常以字符串常量的形式出现。
格式字符串包含格式指定符 (格式代码) 以及一些普通字符。这些普通字符将按照原样逐字打印出来,但每个格式指定符将使后续参数的值按照它所指定的格式打印。如果数组 input
包含字符串 Hi friend!
,那么下面这条语句
printf(“Original input: %s\n”, input);
的打印结果是:
Original input: Hi friends!
后面以一个换行符终止。
NUL
是 ASCII 字符集中 '\0'
字符的名字,它的字节模式为全 0。NULL
指一个其值为 0 的指针。它们都是整型值,其值也相同,所以它们可以互换使用。然而,你还是应该使用适当的常量,因为它能告诉阅读程序的人不仅使用。这个值,而且告诉他使用这个值的目的。
符号 NULL
在头文件 stdio.h
中定义。另一方面,并不存在预定义的符号 NUL
,所以如果你想使用它而不是字符常量 '\0'
,你必须自行定义。
2. C/C++ 题目
计算字符串最后一个单词的长度,单词以空格隔开。
输入描述:
一行字符串,非空,长度小于 5000。
输出描述:
整数 N,最后一个单词的长度。
示例 1
输入
hello world
输出
5
3. gets
函数
//============================================================================
// Name : input
// Author : Yongqiang Cheng
// Version : Version 1.0.0
// Copyright : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <stdio.h>
#include <string.h>
int compute_word_length(const char *input_string)
{
const char *string_pointer = input_string;
int string_length = 0;
int idx = 0;
int word_length = 0;
if (NULL == input_string)
{
return 0;
}
string_length = strlen(input_string);
if (0 == string_length)
{
return 0;
}
for (idx = string_length - 1; string_pointer[idx] != ' '; idx--)
{
word_length++;
if (string_length == word_length)
{
break;
}
}
return word_length;
}
int main()
{
char input_string[5000] = { 0 };
int word_length = 0;
if (NULL == gets(input_string))
{
return 0;
}
word_length = compute_word_length(input_string);
printf("%d\n", word_length);
return 0;
}
21:04:25 **** Build of configuration Debug for project yongqiang_example ****
make all
Building file: ../src/yongqiang.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/yongqiang.d" -MT"src/yongqiang.o" -o "src/yongqiang.o" "../src/yongqiang.c"
../src/yongqiang.c: In function ‘main’:
../src/yongqiang.c:48:14: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
if (NULL == gets(input_string))
^
../src/yongqiang.c:48:11: warning: comparison between pointer and integer
if (NULL == gets(input_string))
^
Finished building: ../src/yongqiang.c
Building target: yongqiang_example
Invoking: GCC C Linker
gcc -o "yongqiang_example" ./src/yongqiang.o
./src/yongqiang.o: In function `main':
/home/strong/eclipse-work/yongqiang_example/Debug/../src/yongqiang.c:48: warning: the `gets' function is dangerous and should not be used.
Finished building target: yongqiang_example
21:04:26 Build Finished (took 551ms)
qiang
5
4. fgets
函数
char * fgets ( char * str, int num, FILE * stream );
gets
函数对输入的字符个数没有限制,容易造成越界。函数执行需要一个栈空间,但这个栈空间容量是有限的,而且栈里存放了函数返回的地址。gets
函数在获取输入时,如果无限输入会造成栈空间溢出,在程序返回时,不能正常的找到返回地址,程序将发生不可预测行为。fgets
函数是为读取文件设计的,fgets
函数会默认在字符串末尾加上’\n’
,影响数据的准确性。使用fgets
函数,注意去掉末尾的换行符’\n’
。
fgets
会认为用户输入的回车也是字符串的一部分内容。fgets
是安全的,不会因为用户恶意的输入过长的字符串导致溢出。因为它只接受它能存的最大的字符数,其余的舍掉!
//============================================================================
// Name : input
// Author : Yongqiang Cheng
// Version : Version 1.0.0
// Copyright : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <stdio.h>
#include <string.h>
int compute_word_length(const char *input_string)
{
const char *string_pointer = input_string;
int string_length = 0;
int idx = 0;
int word_length = 0;
if (NULL == input_string)
{
return 0;
}
string_length = strlen(input_string);
if (0 == string_length)
{
return 0;
}
for (idx = string_length - 1; string_pointer[idx] != ' '; idx--)
{
word_length++;
if (string_length == word_length)
{
break;
}
}
return word_length;
}
int main()
{
char input_string[5000] = { 0 };
int word_length = 0;
fgets(input_string, sizeof(input_string), stdin);
if ('\n' == input_string[strlen(input_string) - 1])
{
input_string[strlen(input_string) - 1] = '\0';
}
word_length = compute_word_length(input_string);
printf("%d\n", word_length);
return 0;
}
21:51:11 **** Build of configuration Debug for project yongqiang_example ****
make all
Building file: ../src/yongqiang.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/yongqiang.d" -MT"src/yongqiang.o" -o "src/yongqiang.o" "../src/yongqiang.c"
Finished building: ../src/yongqiang.c
Building target: yongqiang_example
Invoking: GCC C Linker
gcc -o "yongqiang_example" ./src/yongqiang.o
Finished building target: yongqiang_example
21:51:12 Build Finished (took 523ms)
qiang
5
5. scanf
函数
#include <stdio.h>
#include <string.h>
int compute_word_length(const char *input_string)
{
const char *string_pointer = input_string;
int string_length = 0;
int idx = 0;
int word_length = 0;
if (NULL == input_string)
{
return 0;
}
string_length = strlen(input_string);
if (0 == string_length)
{
return 0;
}
for (idx = string_length - 1; string_pointer[idx] != ' '; idx--)
{
word_length++;
if (string_length == word_length)
{
break;
}
}
return word_length;
}
int main()
{
char input_string[5000] = { 0 };
int word_length = 0;
int idx = 0;
while (EOF != scanf("%c", &(input_string[idx])))
{
idx++;
}
if ('\n' == input_string[strlen(input_string) - 1])
{
input_string[strlen(input_string) - 1] = '\0';
}
word_length = compute_word_length(input_string);
printf("%d\n", word_length);
return 0;
}
6. gets_s
函数
Reads characters from stdin
until a newline is found or end-of-file occurs. Writes only at most n-1
characters into the array pointed to by str
, and always writes the terminating null character (unless str
is a null pointer). The newline character, if found, is discarded and does not count toward the number of characters written to the buffer.
从 stdin
中读取字符,直到找到换行符或出现文件结尾。最多只能将 n-1
个字符写入 str
指向的数组,并且始终写入终止的空字符 (除非 str
是空指针)。 如果找到换行符,则将其丢弃,并且不计入写入缓冲区的字符数。
//============================================================================
// Name : input
// Author : Yongqiang Cheng
// Version : Version 1.0.0
// Copyright : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <stdio.h>
#include <string.h>
int compute_word_length(const char *input_string)
{
const char *string_pointer = input_string;
int string_length = 0;
int idx = 0;
int word_length = 0;
if (NULL == input_string)
{
return 0;
}
string_length = strlen(input_string);
if (0 == string_length)
{
return 0;
}
for (idx = string_length - 1; string_pointer[idx] != ' '; idx--)
{
word_length++;
if (string_length == word_length)
{
break;
}
}
return word_length;
}
int main()
{
char input_string[5000] = { 0 };
int word_length = 0;
if (NULL == gets_s(input_string, sizeof(input_string)))
{
return 0;
}
word_length = compute_word_length(input_string);
printf("%d\n", word_length);
return 0;
}