正如已经指出的,直接的问题是你试图从函数外部调用sprintf
。
你提到你是这样设置字符串的,因为除了将它与路径连接在一起之外,你自己也使用SITE_NAME
,并且你只需要在一个地方改变它。这是一个很好的目标,在一些圈子中被称为"don't repeat yourself" (often abbreviated DRY)。然而,即使代码的工作(比如,因为你的移动电话sprintf
到主),你还没有真正实现你的目标,由于以下行:
char SITE_ROOT[19];
您声明固定长度正好阵大足以容纳"/var/www/html/test"
,这只是要求缓冲区溢出。当您将SITE_NAME
从"test"
更改为例如"someRealSiteName"
时,连接时很可能会覆盖其他内容,从而导致不可预知的结果。因此,每次更改SITE_NAME
时,必须手动重新计算最终字符串的长度并更新数组大小(这很容易出错,比如忘记为空终止符添加1)。
当然,您可以限制SITE_NAME
的长度和尺寸SITE_ROOT
以保持尽可能长的路径,但这是人为的限制,最终可能会浪费空间。此外,您仍然必须验证在运行时长度没有超出(或使用忽略多余字符的函数)。
相反,你可以动态设置的SITE_ROOT
大小,像这样:
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
const char SITE_PATH[] = "/var/www/html/";
const char SITE_NAME[] = "someRealSiteName";
char *SITE_ROOT = NULL; // just making this explicit, would be set to 0 anyway
int main(void)
{
size_t siteRootLength = strlen(SITE_PATH) + strlen(SITE_NAME);
SITE_ROOT = malloc(siteRootLength + 1); //don't forget to account for the terminating '\0'
strcpy(SITE_ROOT, SITE_PATH);
strcat(SITE_ROOT, SITE_NAME);
printf("%s\n", SITE_NAME):
printf("%s\n", SITE_PATH):
printf("%s\n", SITE_ROOT):
return 0;
}
该解决方案是好的,但也有一些缺点:
SITE_ROOT
不能是const
指针,所以字符串和指针本身都可能被意外更改
- 网站路径和名称将分别在内存中两次(虽然听起来好像你没有问题)
- 串联是在运行时正在做时,它可以在编译时完成
- 代码为
- 风险是
SITE_ROOT
使用它具有正确的值之前超过必要的时间和更复杂的这样一个简单的任务(或甚至是一个有效的指针/字符串!)在其他一些初始化代码或另一个线程。
我觉得像下面是更好:
#include <stdio.h>
#define SITE_PATH_MACRO "/var/www/html/"
#define SITE_NAME_MACRO "someRealSiteName"
// the preprocessor will merge the two string literals into one
#define SITE_ROOT_MACRO SITE_PATH_MACRO SITE_NAME_MACRO
// you could do without some or all of these if you don't need them
// (or are willing to use the macros directly)
const char SITE_PATH[] = SITE_PATH_MACRO;
const char SITE_NAME[] = SITE_NAME_MACRO;
const char SITE_ROOT[] = SITE_ROOT_MACRO;
int main(void)
{
printf("%s\n", SITE_NAME);
printf("%s\n", SITE_PATH);
printf("%s\n", SITE_ROOT);
return 0;
}
哪条线是给你的错误? – 2013-05-26 02:57:00
@JackManey - 我更新了我的帖子......错误在sprintf行。 – user983223
意想不到的宏可能会搞砸了。检查预处理器输出。 ('cc -E file.c'用于类似unix的编译器;如果您需要更多帮助,请告诉您使用的编译器) –