scanf连续读取字符串
注意逗号处理,除第一个单词以外,每个单词前都有逗号
#include <stdio.h>
#include <string.h>
int main() {
char s[100];
int flag = 1; // 使用 1 表示第一个单词
while (scanf("%s", s) == 1) {
if (flag) {
flag = 0;
printf("%lu", strlen(s));
} else {
printf(",%lu", strlen(s));
}
}
return 0;
}
该题还可以读入一整行后做处理
读取一整行
可选用函数有fgets,gets,和scanf("%[^\n]",s)三种
scanf("%[^\n]", str) 和 gets(str) 都可以用来读取一行字符串,但它们之间有以下区别:
安全性:scanf 函数在处理字符串时存在潜在的缓冲区溢出问题,因为它没有指定最大输入长度。如果输入的字符串超过了目标数组的大小,就会导致缓冲区溢出。而 gets 函数更不安全,因为它没有提供字符数目的限制,可能导致更严重的内存溢出问题。而fgets最安全但会读取末尾的换行符,造成最后一个数字在编译器上测试时可能会大1,而在洛谷ide交题无碍。
指针
#include <stdio.h>
int main() {
char str[1000];
fgets(str, 1000, stdin); // 读取输入的字符串
char *ptr = str;
while (*ptr != '\0') {
if (*ptr != ' ') { // 如果当前字符不是空格
int length = 0;
while (*ptr != ' ' && *ptr != '\0') { // 统计单词长度
length++;
ptr++;
}
printf("%d", length);
if (*ptr != '\0') {
printf(","); // 输出逗号
}
} else {
ptr++;
}
}
return 0;
}
对于第二个while循环,条件要注意
while (*ptr != ' ' && *ptr != '\0')
不仅考虑空格还要考虑指针不能越界
strtok(逗号处理更自然)
#include <stdio.h>
#include <string.h>
int main()
{
char s[1000];
char str[]=" ";
scanf("%[^\n]",s);
char*token=strtok(s,str);
while(token!=NULL)
{
printf("%lu",strlen(token));
token=strtok(NULL,str);
if(token!=NULL)
{
printf(",");
}
}
}
strtok函数返回被分解的第一个子字符串,若无可检索的字符串,则返回空指针
注意:在这个函数里strtok()在分解字符串的时候,第一个参数是在不断变化的,这个函数是在改变原字符串,所以第一个字符串不能是常量字符串
strtok简化版函数源码
char *strtok(char *str, const char *delim) {
static char *next_start = NULL; // 保存到静态存储区,函数返回后不会被销毁
// 如果传入的 str 为 NULL,并且 next_start 也为 NULL,则返回 NULL
if (str == NULL && (str = next_start) == NULL) {
return NULL;
}
char *s = str; // 初始化 s 指针指向传入的字符串
const char *t = NULL; // t 是分隔符字符串 delim 的指针
// 遍历字符串直到结束
while (*s) {
t = delim; // 将 t 指针指向分隔符字符串
// 遍历分隔符字符串 delim
while (*t) {
if (*t == *s) { // 如果发现当前字符是分隔符
next_start = s + 1; // 更新 next_start 指向下一个待处理字符的位置
if (s == str) { // 如果第一个字符就是分隔符
str = next_start; // 更新 str 指针指向下一个待处理字符的位置
break; // 跳出内层循环
} else {
*s = '\0'; // 将当前字符设为字符串结尾
return str; // 返回上一个子字符串的起始地址
}
} else {
t++; // 继续比较下一个分隔符字符
}
}
s++; // 继续处理下一个字符
}
return NULL; // 处理完整个字符串后返回 NULL
}
next_start 是一个静态指针,在函数内部用来保存下一个待处理字符的位置。它的作用是在多次调用 strtok 函数时,保持上一次处理结束后下一个待处理字符的位置,从而实现对同一个字符串的连续分割。
具体来说,next_start 的作用是记录上一次 strtok 函数处理的位置,以便下一次调用 strtok 时能够从上一次结束的地方继续处理字符串。这样可以实现在一个循环中多次调用 strtok 来逐个获取被分割的子字符串。