如何从c字符串中读取特定数量的字符?
使用如何从c字符串中读取特定数量的字符?,c,string,C,String,使用intsnprintf(字符*str,大小\u t大小,常量字符*格式,…) 我可以将特定数量的字符写入str 如何从c字符串中读取特定数量的字符 关于您可以在format参数中传递一个数字: char buf[21]; sscanf(str, "%20s", buf); 这会将最多20个字符读入buf 如果不知道编译时要读取多少数据,可以在运行时准备格式字符串: char format[20]; sprintf(format, "%%%ds", howMuchToRead); sscan
intsnprintf(字符*str,大小\u t大小,常量字符*格式,…)代码>
我可以将特定数量的字符写入str
如何从c字符串中读取特定数量的字符
关于您可以在format参数中传递一个数字:
char buf[21];
sscanf(str, "%20s", buf);
这会将最多20个字符读入buf
如果不知道编译时要读取多少数据,可以在运行时准备格式字符串:
char format[20];
sprintf(format, "%%%ds", howMuchToRead);
sscanf(str, format, buf);
您可以使用strncpy
或memcpy
。但是,请注意,在某些情况下,strncpy
可能不会追加终止的'\0'
字符,而且memcpy
永远不会追加。另外,memcpy
根本不检查字符串的结尾,它只是复制您请求它的字节数。您可以使用sscanf
:
int sscanf(const char *str, const char *format, ...);
例如:
char out[4];
sscanf("foo", "%3s", &out);
当然,你也可以做一些更有趣的事情:
int value;
sscanf("value=10", "value=%d", &value);
sscanf
与scanf
功能一样,存在问题。正如GNU手册所说:
对于给定的格式说明符,必须有足够的地址参数;如果不是这样,结果是不可预测的,很可能是灾难性的
因此,您需要避免一个问题(编译器无法为您验证是否传递了正确数量或类型的参数,尽管有些编译器有专门针对这些函数的警告)。这个问题的一部分还在于,您需要硬编码格式字符串中的最大缓冲区大小(这使得使用整数常量来防止缓冲区溢出更加困难)
因为您的用例只是从一个字符串中复制到一定数量的字符,所以我只使用Joachim Pileborg的答案建议的strncpy
(并确保设置一个终止的'\0'
)。对于长度参数,您应该使用输入和输出缓冲区的最小长度减去1以适应终止nul
换句话说(未经测试):
其中MIN(a,b)
等同于a
关于整数。除了这两种方法和解决方案之外,您还可以使用精度说明符(例如“%.20s”
仅打印20个字符)。中讨论了C字符串的精度说明符。这些步骤基本上与在sscanf
解决方案中相同,您可以创建一个格式字符串并使用它捕获所需的字符。
在使用sscanf
时,如果您使用上述格式说明符,即%20s”
等,则不能保证如果字符串包含空格,您将获得20个字符;如果遇到空白,则只能在空白之前获取字符(因为空白是scanf
函数系列的分隔符)。相反,您应该使用类似于%20[^\n]
的东西<代码>[^\n]
表示直到换行时才读取,而20指定要扫描的字符数。所有这些都可以从以下方面看出:
#包括
#包括
内部主(空){
字符格式[20]={0};
char buf[50]={0};
char str[]=“你好,世界!你好吗?”;
大小\u t howMuchToRead=8;
/*使用sscanf-直到指定空白或大小*/
snprintf(格式,大小格式,“%%%zus”,howMuchToRead);
sscanf(str,格式,buf);
printf(“使用%%8s格式的sscanf:%s\n”,buf);
/*使用sscanf-阅读所有内容直到换行*/
snprintf(格式,大小格式,“%%%zu[^\n]”,howMuchToRead);
sscanf(str,格式,buf);
printf(“使用%%8[^\\n]格式的sscanf:%s\n”,buf);
/*使用精度说明符*/
snprintf(格式,sizeof格式,“%%.%zus”,howMuchToRead);
snprintf(buf,sizeof buf,format,str);
printf(“使用精度说明符:%s\n”,buf);
返回0;
}
/*
输出:
使用%8s格式的sscanf:Hello
使用具有%8[^\n]格式的sscanf:Hello Wo
使用精度说明符:Hello Wo
*/
并提出一些非常重要的要点,你应该注意这些要点。希望这有帮助 你说的“从c字串读取”到底是什么意思?如果您已经有了字符串,您只需访问数组(考虑nul终止符)并读取您想要的任何内容+1@betabandido这个问题没有太多的解决方案:)@dasblinkenlight:问题是我从用户那里得到了一个变量
size\u t howmuchtoard代码>。我可以将其与您的解决方案结合起来吗?@ron当然可以,您可以在运行时准备格式(请参阅上一次编辑的示例)。编译器无法验证sscanf
调用参数(尽管有些编译器会发出警告)。我想说,sscanf是以静态类型安全性为代价来解决这一问题的完全过度。
strncpy(dest, src,
MIN(NUM_OF_CHARS_TO_COPY,
MIN(DEST_BUFFER_SIZE, SRC_BUFFER_SIZE)) - 1);
#include <stdio.h>
#include <string.h>
int main(void) {
char format[20] = {0};
char buf[50] = {0};
char str[] = "Hello World! How are you?";
size_t howMuchToRead = 8;
/* Using sscanf - till whitespace or size specified */
snprintf(format, sizeof format, "%%%zus", howMuchToRead);
sscanf(str, format, buf);
printf("Using sscanf with %%8s format :%s\n", buf);
/* Using sscanf - read everything upto newline */
snprintf(format, sizeof format, "%%%zu[^\n]", howMuchToRead);
sscanf(str, format, buf);
printf("Using sscanf with %%8[^\\n] format :%s\n", buf);
/* Using precision specifier */
snprintf(format, sizeof format, "%%.%zus", howMuchToRead);
snprintf(buf, sizeof buf, format, str);
printf("Using precision specifier :%s\n", buf);
return 0;
}
/*
Output:
Using sscanf with %8s format :Hello
Using sscanf with %8[^\n] format :Hello Wo
Using precision specifier :Hello Wo
*/