如何从c-string中读取特定数量的字符?

时间:2012-07-18 10:51:00

标签: c string

int snprintf(char *str, size_t size, const char *format, ...); 我可以将特定数量的字符写入str

如何从c字符串中读取特定数量的字符?

问候

5 个答案:

答案 0 :(得分:6)

您可以使用格式参数传递数字:

char buf[21];
sscanf(str, "%20s", buf);

最多可在buf中读取20个字符。

如果您不知道在编译时要读取多少数据,可以在运行时准备格式字符串:

char format[20];
sprintf(format, "%%%ds", howMuchToRead);
sscanf(str, format, buf);

答案 1 :(得分:4)

替代sscanfstrncpy解决方案,您还可以使用精确说明符(如"%.20s"只打印20个字符)。 {em> C string 的精度说明符已在this SO post中讨论过。这些步骤与sscanf解决方案中的步骤基本相同,您可以创建格式字符串&用它来捕捉所需的角色 使用sscanf时如果使用上面提到的格式说明符,即"%20s"等,如果字符串包含空格,则不能保证得到20个字符;如果遇到空格,那么你将只获得字符直到空格(因为空格是scanf函数族的分隔符)。相反,你应该使用%20[^\n]之类的东西。 [^\n]表示读取到换行符,而20表示要扫描的字符数。所有这些都可以在the following sample中找到:

#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
*/

sinelaw's answer提出了非常重要的一点,你应该小心 希望这有帮助!

答案 2 :(得分:2)

您可以使用strncpymemcpy。但是,请注意strncpy在某些情况下可能不会附加终止'\0'字符,而memcpy永远不会。此外,memcpy根本不检查字符串的结尾,它只是复制您要求它的字节数。

答案 3 :(得分:2)

您可以使用sscanf

int sscanf(const char *str, const char *format, ...);

例如:

char out[4];
sscanf("foo", "%3s", &out);

当然,你也可以做一些有趣的事情:

int value;
sscanf("value=10", "value=%d", &value);

答案 4 :(得分:2)

sscanfscanf功能一样,存在问题。正如GNU手册页所说:

  

给定的格式说明符必须有足够的地址参数;如果不是,结果是不可预测的,可能是灾难性的。

因此,您需要避免一个问题(编译器无法验证您是否正在传递正确数量或类型的参数,尽管某些编译器有一个黑客警告您特别是关于这些功能)。部分问题还在于您需要对格式字符串中的最大缓冲区大小进行硬编码(这使得使用整数常量更难以防止缓冲区溢出)。

由于您的用例只是从字符串中复制到一定数量的字符,因此我只需使用strncpy(并确保根据建议设置终止'\0')通过Joachim Pileborg的回答。对于length参数,您应该使用输入和输出缓冲区的最小长度减去1以适应终止nul

换句话说(未经测试):

strncpy(dest, src, 
        MIN(NUM_OF_CHARS_TO_COPY, 
            MIN(DEST_BUFFER_SIZE, SRC_BUFFER_SIZE)) - 1);

其中MIN(a,b)相当于整数上的a < b ? a : b

相关问题