思路? 如何能使CString Format("%d ..",x, , ,)输入参数自动化??

vc8fans 2014-09-03 08:55:08

在使用CString 类的 Format 给字串 对应赋值,常常有不确定数量的值如:
CString strSQL;

strSQL.Format("Insert into DB_TEST(ID,S1,S2) Values ('%s','%s','%s') ", s1,s2 ,s3 );

switch(num)
{
case 1:
strSQL.Format("Insert into DB_TEST(ID,) Values ('%s'') ", s1,s2 );
break;
case 2:
strSQL.Format("Insert into DB_TEST(ID,S1) Values ('%s','%s') ", s1,s2 );
break;
case 3:
strSQL.Format("Insert into DB_TEST(ID,S1,S2) Values ('%s','%s','%s') ", s1,s2 ,s3 );
break;
.....
}

因为不确定的数量太多,,如何能简单的实现,按变量多少自动,实现Format 赋值????



}
...全文
201 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
你妹的特盗不 2014-09-04
  • 打赏
  • 举报
回复
引用 11 楼 vc8fans 的回复:
CString Field[]={"ID","S1","S2"}; //字段名称 CString strValue[]={"001","name","sex"}; //字段对应要传入的值 int max =3; //因为只有三组,插入更多,就相应增加 CString strSQL; strSQL = " "Insert into DB_TEST("; for(int i=0; i<max; i++) { strSQL = strSQL + Field[i]; //第一部把三个字段名称传输完毕 if(i<max-1) strSQL = strSQL + ","; } strSQL =strSQL + ") Values ("; //第二部分把中间词填完 for(int i=0; i<max; i++) { strSQL = strSQL +"'" +strValue[i] + "'"; //第三部把三个字段对应值传输完毕 if(i<max-1) strSQL = strSQL + ","; } strSQL =strSQL + ") "; //第四部分,把最后)补上,,
你这方法可行,我就是这么干的
vc8fans 2014-09-04
  • 打赏
  • 举报
回复
CString Field[]={"ID","S1","S2"}; //字段名称 CString strValue[]={"001","name","sex"}; //字段对应要传入的值 int max =3; //因为只有三组,插入更多,就相应增加 CString strSQL; strSQL = " "Insert into DB_TEST("; for(int i=0; i<max; i++) { strSQL = strSQL + Field[i]; //第一部把三个字段名称传输完毕 if(i<max-1) strSQL = strSQL + ","; } strSQL =strSQL + ") Values ("; //第二部分把中间词填完 for(int i=0; i<max; i++) { strSQL = strSQL +"'" +strValue[i] + "'"; //第三部把三个字段对应值传输完毕 if(i<max-1) strSQL = strSQL + ","; } strSQL =strSQL + ") "; //第四部分,把最后)补上,,
vc8fans 2014-09-04
  • 打赏
  • 举报
回复
非常感谢楼上的回复,我昨天想了很久,有一个思路比较原始请大家看 例如: "Insert into DB_TEST(ID,S1,S2) Values ('%s','%s','%s') ", s1,s2 ,s3 ); CString Field[]={"ID","S1","S2"}; //字段名称 CString strValue[]={"001","name","sex"}; //字段对应要传入的值 int max =3; //因为只有三组,插入更多,就相应增加 CString strSQL; strSQL = " "Insert into DB_TEST("; for(int i=0; i<max; i++) strSQL = strSQL + Field[i]; //第一部把三个字段名称传输完毕 strSQL =strSQL + ") Values ("; //第二部分把中间词填完 for(int i=0; i<max; i++) { strSQL = strSQL +"'" +strValue[i] + "'"; //第三部把三个字段对应值传输完毕 if(i<max-1) strSQL = strSQL + ","; } strSQL =strSQL + ") "; //第四部分,把最后)补上,, ========================================================================= 思路: CString Field[]={"ID","S1","S2".....}; //字段名称 CString strValue[]={"001","name","sex".....}; //字段对应要传入的值 int max=N; 只要有 N个增加值,还是用上面代码,从而实现SQL代码自动化,,,包括更新,查询等,, CString Field[] ....等可用可变数组代替。。。,大家看这个思路对吗????
vc8fans 2014-09-04
  • 打赏
  • 举报
回复
谢谢...!
「已注销」 2014-09-03
  • 打赏
  • 举报
回复
因为你的字段名也是可变的,所以这部分必须动态生成。即把字段名独立成为一个参数,按照我的那个代码传进去。当然,你也可以写在循环里面。不过参数的个数不重要,因为 __cdecl 是调用者清理堆栈,所以你不需要关心参数个数是否传对,你只需要保证 “...” 部分传进去的参数个数大于等于格式化字符串中的 %s 的个数即可。重点是字段名这部分需要先拼接好,才能形成最终的格式化字符串。我将代码稍作修改,变成这个样子:
static void __cdecl FormatSQLStr(CStringA &strRetSQL, const CStringA &strSQLFmt, CStringA astrCol[], int count, ...)
{
    if (count > 0) {
        CStringA strCols = "";
        CStringA strVals = "";
        for (int i = 0; i < count; i++) {
            if (i > 0) {
                strVals += ",'%s'";
                strCols += "," + astrCol[i];
            } else {
                strVals = "'%s'";
                strCols = astrCol[0];
            }
        }
 
        CStringA strRetFmt;
        strRetFmt.Format(strSQLFmt, strCols, strVals);
 
        va_list vl = NULL;
        va_start(vl, count);
        strRetSQL.FormatV(strRetFmt, vl);
        va_end(vl);
    }
}
 
CStringA strRetSQL[3];
CStringA astrCol[3] = { "ID", "S1", "S2" };
for (int i = 0; i < 3; i++) {
    FormatSQLStr(strRetSQL[i], "INSERT INTO DB_TEST (%s) VALUES (%s)", astrCol, i + 1, s1, s2, s3);
}
最终 strRetSQL 这个数组应该能得到:
INSERT INTO DB_TEST ('ID') VALUES (s1的值)
INSERT INTO DB_TEST ('ID','S1') VALUES (s1的值,s2的值)
INSERT INTO DB_TEST ('ID','S1','S2') VALUES (s1的值,s2的值,s3的值)
代码未测试,可能需要修改。
vc8fans 2014-09-03
  • 打赏
  • 举报
回复
非常感谢,因为这个经常要用,马上去试一下。。。
SiGoYi 2014-09-03
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdarg.h>

void testit ( int i, ...)
{
   va_list argptr;
   va_start(argptr, i);

   if ( i == 0 ) {
      int n = va_arg( argptr, int );
      printf( "%d\n", n );
   } else {
      char *s = va_arg( argptr, char* );
      printf( "%s\n", s);
   }
}

int main()
{
   testit( 0, 0xFFFFFFFF ); // 1st problem: 0xffffffff is not an int
   testit( 1, NULL );       // 2nd problem: NULL is not a char*
}
可以参考msdn上的例子,在msdn上收一下 va_list ,学习一下吧,可以解决你的问题。
boyka913 2014-09-03
  • 打赏
  • 举报
回复
用宏定义,也许可以,你可以试试
lx624909677 2014-09-03
  • 打赏
  • 举报
回复
自己写一个带可变参数的函数,然后这样处理
void testLog(char* fmt,...)
{
	CString strLog;
	va_list argp;
	va_start(argp,fmt);
	strLog.FormatV(fmt,argp);
	va_end(argp);
	AfxMessageBox(strLog);
}
vc8fans 2014-09-03
  • 打赏
  • 举报
回复
int S[N]; strSQL.Format(str, S[0], S[1] ....); //str 内容可增加,,S[N] 数据不定,但类型固定,,后面赋值,,数量能不能用循环来实现???
vc8fans 2014-09-03
  • 打赏
  • 举报
回复
用: va_list argp; va_start(argp,fmt); strLog.FormatV(fmt,argp); va_end(argp); 与strSQL.Format("Insert into DB_TEST(ID,S1,S2) Values ('%s','%s','%s') ", s1,s2 ,s3 );相同效果: 我的意思如何产生这种效果 strSQL.Format("Insert into DB_TEST(ID,S1,S2) Values ('%s','%s','%s') ", s1,+ s2 +,s3+...... ); 就是后面变化如何动态加上不是固定写,前面string可以用 string + string 方式后面,S1, S2,S3) 能不能用循环自动产生 strSQL.Format(str, s1,s2 ); strSQL.Format(str s1,s2 ); strSQL.Format(str, s1,s2 ,s3 ); 以上三个变量三个赋值语句 能不能用一个循环完成后面哪怕有N个, int S[N]; for(i=0; i<N; i++) strSQL.Format(str, s[0],,,,); //自动生成后面变量的代码,,,代码自动化问题,????
「已注销」 2014-09-03
  • 打赏
  • 举报
回复
尚未测试是否可以通过编译,但可以参考此思路。
static void __cdecl GetSQLStr(CStringA &strSQL, int count, ...)
{
    if (i > 0) {
        CStringA strCols = "";
        CStringA strVals = "";
        CStringA astrCol[] = { "ID", "S1", "S2" };
        for (int i = 0; i < count; i++) {
            if (i > 0) {
                strVals += ",'%s'";
                strCols += "," + astrCol[i];
            } else {
                strVals = "'%s'";
                strCols = astrCol[0];
            }
        }

        CStringA strFmt = "INSERT INTO DB_TEST (" + strCols + ") VALUES (" + strVals + ")";

        va_list vl = NULL;
        va_start(vl, count);
        strSQL.FormatV(strFmt, vl);
        va_end(vl);
    }
}

int main(int argc, char *argv[])
{
    CStringA strSQL;
    GetSQLStr(strSQL, 1, s1);
    GetSQLStr(strSQL, 2, s1, s2);
    GetSQLStr(strSQL, 3, s1, s2, s3);
    return 0;
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧