只打印一个指向所需长度的指针

时间:2011-10-25 12:13:24

标签: c string pointers segmentation-fault memcpy

我有这样的C函数..

func(uint8_t *key,uint8_t keylen) {

FILE *fk;
fk=fopen("akey","wb");
fwrite((char *)key,keylen,1,fk);

puts((char *)key); // for testing

fclose(fk);

sprintf(sstring,"... \"%s\" ... ",(char *)key);
        // ...other irrelevant stuff for here
system(sstring);


}

我希望提供的密钥作为输入使用 在\"%s\"命令

中标记为sprintf的地方

输入:

  Key=qwerty

输出

 $cat akey
 qwerty

puts((char *)key)的输出是 -

 qwerty�    

 // include newline character as well

建议我这个,我尝试了这个(在他们各自的代码位置) 但得到segmentation fault

    char *p;
    memcpy(p,(char *)key,keylen);
    puts((char *)p);

3 个答案:

答案 0 :(得分:5)

您可以使用%.*s形式将其打印出来:

printf("%.*s\n", (int)keylen, (char *)key);
...
sprintf(sstring,"... %.*s ... ", ... (int)keylen, (char *)key ...);

这是printfWikipedia entry的摘录:

  

可以省略宽度和精度格式化参数,或者它们   可以是嵌入在格式字符串中的固定数字,也可以作为传递   另一个函数参数,由星号“*”表示   格式字符串。例如printf(“%* d”,5,10)将导致“10”   正在打印,总宽度为5个字符,printf(“%。* s”,   3,“abcdef”)将导致打印“abc”。

注意:使用8位类型(uint8_t)表示长度,将字符串的长度限制为255个字符。更好的是使用size_t

答案 1 :(得分:1)

你需要空终止你的字符串(添加一个尾随的'\ 0'字节)或使用%ns(如qwerty的“%.5s”。首选Null终止。

答案 2 :(得分:1)

sprintf期望以0结尾的字符串。在您的应用程序中可能不是这种情况。关于使用memcpy - 您需要先分配内存。还要确保检查错误,例如是否fk != NULL

内存分配示例:

char *p = malloc(keylen + 1);
// check that p != NULL here
memcpy(p,(char *)key,keylen);
p[keylen] = 0;
puts((char *)p);
free(keylen);