const char *SITE_NAME = "test";
char SITE_ROOT[19];
sprintf (SITE_ROOT, "/var/www/html/%s", SITE_NAME);
我无法弄清楚为什么我会收到错误:
错误:预期')'字符串常量
之前
基本上我只想将变量SITE_NAME连接到SITE_ROOT上。错误发生在sprintf行上。有任何想法吗?
更新:如果代码在main()中,代码就可以工作。我把它放在main()之外,以便我可以在函数内部使用这些变量。
答案 0 :(得分:4)
错误看起来可能没有在代码中显示,但sprintf
应该是:
sprintf (SITE_ROOT, "/var/www/html/%s", SITE_NAME);
修改
如果有任何帮助,这是我的完整测试代码:
#include <string.h>
#include <stdio.h>
int main()
{
const char *SITE_NAME = "test";
char SITE_ROOT[19];
sprintf (SITE_ROOT, "/var/www/html/%s", SITE_NAME);
printf( "%s\n", SITE_ROOT ) ;
return 0 ;
}
答案 1 :(得分:2)
正如已经指出的,直接的问题是你试图从函数外部调用sprintf
。
您提到您正在以这种方式设置字符串,因为除了将其与路径连接之外,您还单独使用SITE_NAME
,并且您只需要在一个位置更改它。这是一个很好的目标,在某些圈子中称为"don't repeat yourself" (often abbreviated DRY)。但是,即使代码有效(例如,因为您将sprintf
调用移至main),由于以下行,您还没有真正实现目标:
char SITE_ROOT[19];
您声明一个固定长度的数组,其大小足以容纳"/var/www/html/test"
,这只是要求缓冲区溢出。当您将SITE_NAME
从"test"
更改为"someRealSiteName"
时,您很可能会在连接时覆盖其他内容,从而导致无法预测的结果。因此,每次更改SITE_NAME
时,必须手动重新计算最终字符串的长度并更新数组大小(这很容易出错,比如忘记为null终止符添加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;
}
答案 2 :(得分:1)
由于这是一个非常简单的情况,您可以简单地初始化字符串然后连接到它上面。您可能希望添加检查以确保您不会超出字符串的边界。
strcpy(SITE_ROOT, "/var/www/html/");
strcat(SITE_ROOT, SITE_NAME);