我在C中定义了一个函数,它将长字符串缩短为固定大小并打印缩短的字符串。功能如下:
void fit(char *str,unsigned int size) // shorten long strings to fixed size, "size" and prints the shortened string.
{
if ( strlen(str) > size)
str[size] = '\0';
printf("%s", str); // prints the shortened string
}
如果我运行此函数,编译器指出没有警告也没有错误,但执行停止。代码的哪一部分会使执行停止?
#include <stdio.h>
#include <string.h>
void fit(char *str, unsigned int size);
int main(void)
{
fit("Hello People!!", 6);
}
void fit(char *str,unsigned int size)
{
if ( strlen(str) > size)
str[size] = '\0';
printf("%s", str);
}
答案 0 :(得分:4)
在标准C和C ++中,字符串文字("these"
)是只读的。
通常这些位于只读存储器中。通过在特定示例中写入str
,程序会尝试写入写保护的内存,操作系统(或运行时,如果适用)不允许写入,这会导致程序异常终止。如果您正在编写C ++,编译器可能会抱怨您将const char*
传递给接受非const
参数的函数。
您有四种选择:
告诉编译器把“Hello People !!”在构建或初始化程序时,可写数据区域中的字符串而不是写保护数据 - 这需要编译器或平台特定的功能,而不是标准C或C ++的一部分。
使用特定于操作系统的命令使存储区域可写(玩得开心!)
在修改字符串之前将其复制到可变缓冲区。
使用char str[] = "Hello People!!";
- 这与选项3基本相同,但编译器会为您执行此操作。但是,在离开范围时要小心。
请注意,将空字符插入字符串缓冲区作为缩短字符串的方法可能是个坏主意,因为它会在分配的缓冲区中隐藏额外的空间。通常,您应该将字符串视为不可变的,如果您希望通过以写时复制的方式重用字符串来提高效率,那么请使用指向现存缓冲区的start/end
对,而不是依赖于空终止。
答案 1 :(得分:2)
您可以使用静态字符串初始化您分配的内存,它应该可以正常工作:
#include <stdio.h>
#include <string.h>
void fit(char *string, size_t size);
int main(void)
{
char string[] = "Hello People!!";
fit(string, 6);
printf("%s\n", string);
return 0;
}
void fit(char *string, size_t size)
{
if (strlen(string) > size)
string[size] = '\0';
}
答案 2 :(得分:2)
您正在尝试剪切string literal
,即const char *
,即写保护。
您可以将代码更改为:
#include <stdio.h>
#include <string.h>
void fit(char *str, unsigned int size);
int main(void)
{
char test[] = "Hello People!!";
fit(test, 6);
}
void fit(char *str,unsigned int size)
{
if ( strlen(str) > size)
{
str[size] = '\0';
printf("%s\n", str);
}
else
{
fprintf(stderr, "Size passed greater than string length!\n");
}
}
正如您所看到的,您正在使用文字字符串初始化char(C-String)数组。所以通过引用传递该数组(传递给函数时使用c数组衰减到指针)你可以修改它,结果就是你所期望的。
第二种解决方案是在fit
func:
#include <stdio.h>
#include <string.h>
void fit(char *str, size_t size);
int main(void)
{
fit("Hello People!!", 6);
}
void fit(char *str, size_t size)
{
// One char is added to store null terminator into new string
char cutString[size+1] = {0};
if ( strlen(str) > size)
{
for (size_t i=0; i<size; i++)
{
cutString[i] = str[i];
}
cutString[size] = '\0';
printf("%s\n", cutString);
}
else
{
fprintf(stderr, "Size passed greater than string length!\n");
}
}