从表中取字段值放在一个buff 中,每个字段用"," 隔开,语句是这样写的,
sprintf(recstr,"%s,",buff);
recstr存放每一条记录当遇到汉字字段时,汉字后面有不乱码或是不可见字符,乱码的字节和分隔符逗号竟组成另一种乱码,导致导出的记录少一逗号,敬请高手指点一下!!

解决方案 »

  1.   

    我以前写过一个差不多的程序,如下:
    ========================================
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <pwd.h>
    #include <sqlda.h>
    #include <sqlcpr.h>
    #include <sqlca.h>/*EXEC SQL BEGIN DECLARE SECTION;*/
        VARCHAR username[20] ;
        VARCHAR password[20];/* the "d_" means the database */    struct stu_info{
            VARCHAR User_name[16];
            VARCHAR         Password[64];
      VARCHAR Real_name[16];
            VARCHAR         Credentials[16];
            double          Remain_money;
            VARCHAR         User_class[32]; 
        } stu_info_buf;/*EXEC SQL END DECLARE SECTION;*/void sql_error(msg)
        char *msg;
    {
        char err_msg[128];
        size_t buf_len, msg_len;    EXEC SQL WHENEVER SQLERROR CONTINUE;    printf("\n%s\n", msg);
        buf_len = sizeof (err_msg);
        sqlglm(err_msg, &buf_len, &msg_len);
        printf("%.*s\n", msg_len, err_msg);    EXEC SQL ROLLBACK RELEASE;
        exit(EXIT_FAILURE);
    }main()
    {
      FILE * fp_graduate;
      int i=0;

    /************************************************************************
     * connect_database *
     ************************************************************************/
       strcpy(username.arr,"scott") ;
       username.len = strlen(username.arr) ;
       strcpy(password.arr,"tiger") ;
       password.len = strlen(password.arr) ;
       EXEC SQL CONNECT :username IDENTIFIED BY :password ;
            if(sqlca.sqlcode != 0)
            {
                 printf("Can't connect to database--%d %s.", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
    exit(0);
           }        /************************************************************************
     * write_hostinfo *
     ************************************************************************/fp_graduate=fopen("graduate.txt","w");
    fprintf(fp_graduate,"\n 序号 \t 姓名 \t\t 用户名 \t\t 剩余金额   班级");
     
    EXEC SQL DECLARE graduate_c CURSOR FOR
    select 
      t_userinfo.user_name,
      t_userinfo.password,
      t_userinfo.real_name,
      t_userinfo.credentials,
      t_useracct.remain_money,
      t_graduate.class
    from
      t_userinfo,
      t_useracct,
      t_graduate
    where
         t_userinfo.real_name=t_graduate.real_name 
    and  t_userinfo.credentials=t_graduate.credentials
    and  t_userinfo.user_name=t_useracct.user_name
    ORDER BY t_graduate.class ; 
            EXEC SQL OPEN graduate_c ;
            EXEC SQL WHENEVER NOT FOUND DO break ;
            for(;;)
            {
    i++;
                    EXEC SQL FETCH graduate_c
    into  :stu_info_buf.User_name,
    :stu_info_buf.Password,
    :stu_info_buf.Real_name,
    :stu_info_buf.Credentials,
                                    :stu_info_buf.Remain_money,
                                    :stu_info_buf.User_class;
             stu_info_buf.User_name.arr[stu_info_buf.User_name.len] = '\0';
    stu_info_buf.Password.arr[stu_info_buf.Password.len] = '\0';
    stu_info_buf.Real_name.arr[stu_info_buf.Real_name.len] = '\0';
                    stu_info_buf.Credentials.arr[stu_info_buf.Credentials.len] = '\0';
                    stu_info_buf.User_class.arr[stu_info_buf.User_class.len] = '\0';
                           
    fprintf(fp_graduate,"\n %-4d \t %-8s \t %-16s \t %-4.1f \t    %-16s",
                                       i,stu_info_buf.Real_name.arr,stu_info_buf.User_name.arr,
                                       stu_info_buf.Remain_money,stu_info_buf.User_class.arr);    
            
            }
    EXEC SQL CLOSE graduate_c;
            fclose(fp_graduate);
            EXEC SQL COMMIT RELEASE;
    return;
    err_write_hostinfo:
    printf("ERROR1 write_host_info-- %d, %s", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
    return;
    }====================
    你把fprintf(fp_graduate,"\n %-4d \t %-8s \t %-16s \t %-4.1f \t    %-16s",
    这句中的\t改成逗号就成了.
      

  2.   

    当然了,你还有另一个更方便的选择'
    在sqlplus中,你只用这几个命令就可以把查询内容输入到文本中了,
    set heading off
    set feedback off
    spool someText.txt
    select * from t_table ;
    spool off
    set feedback on
    set heading on
    =====================
    进一步,你就可以把这几句放在proc中就行了
      

  3.   

    asktom 上有现成的高效源码,为什么不用呢?
      

  4.   

    不好意思,这几天廷忙,没来登录
    谢谢各位帮忙,我用的是ORACLE中的SQLDA结构,写的一个通用的,说白了是从网上找的一个略加改了一下,输入SQL查询语句就会按查询的内容输出文本, 能不能通过汉字编码的方式解决此类问题,就是我取出字段值之后,再经过处理,截位,获得正确值.
      

  5.   

    原码是这样的:
    /*---------------------------------------------------------------------------
    函数名称:ExportTxtfile
    函数功能:根据相应的SQL语句,导出指定的文本文件
    入口参数:Sql:正确的SQL语句,FileName:目标文件名
    出口参数: 
    返 回 值: 0 成功
    调用说明:
    备    注:
    ---------------------------------------------------------------------------*/
    int  ExportTxtfile(const char *Sql/*SQL选择语句*/, const char *FileName/*导出目标文本文件名*/)
    {
    int null_ok, precision, scale;
    int i;
    int j;

    FILE* fpot;

    if ((fpot = fopen(FileName,"a")) == NULL)
    {
       return -1;
    }



    EXEC SQL BEGIN DECLARE SECTION;
    char sqlstr[256];
    EXEC SQL END DECLARE SECTION;


    if (bConnect == 0) return -2;

    strcpy(sqlstr, Sql);

    if ((SelectUnit = sqlald(MAX_ITEMS, MAX_VNAME_LEN, MAX_INAME_LEN)) == (SQLDA *)NULL)
    {
    return -3;
    }

    if ((BindUnit = sqlald(MAX_ITEMS, MAX_VNAME_LEN, MAX_INAME_LEN)) == (SQLDA *)NULL)
    {

    return -3;
    }
    SelectUnit->N = MAX_ITEMS;
    for (i=0; i < MAX_ITEMS; i++)
    {
    BindUnit->I[i] = (short *)malloc(sizeof(short *));
    BindUnit->V[i] = (char *)malloc(MAX_VNAME_LEN);
    }
    for (i=0; i < MAX_ITEMS; i++)
    {
    SelectUnit->I[i] = (short *)malloc(sizeof(short *));
    SelectUnit->V[i] = (char *)malloc(MAX_VNAME_LEN);
    }

    /*EXEC SQL WHENEVER SQLERROR goto sqlerr;*/

    EXEC SQL PREPARE SQLSA FROM :sqlstr;
    EXEC SQL DECLARE Cursorbase CURSOR FOR SQLSA;


    BindUnit->N = MAX_ITEMS;
    EXEC SQL DESCRIBE BIND VARIABLES for SQLSA INTO BindUnit;

    if (BindUnit->F < 0)
    {
    return -4;

    }
    BindUnit->N = BindUnit->F;

    EXEC SQL OPEN Cursorbase USING DESCRIPTOR BindUnit;


    EXEC SQL DESCRIBE SELECT LIST for SQLSA INTO SelectUnit;

    if (SelectUnit->F < 0)
    {
    return -4;

    }
    SelectUnit->N = SelectUnit->F;

    for (i=0; i < SelectUnit->F; i++)
    {
    sqlnul(&(SelectUnit->T[i]), &(SelectUnit->T[i]), &null_ok);
    switch (SelectUnit->T[i])
    {
    case 1:
    break;
    case 2:
    sqlprc(&(SelectUnit->L[i]), &precision, &scale);
    if (precision == 0)
    precision = 40;
    SelectUnit->L[i] = precision + 2;
    break;
    case 8:
    SelectUnit->L[i] = 240;
    break;
    case 11:
    SelectUnit->L[i] = 18;
    break;
    case 12:
    SelectUnit->L[i] = 9;
    break;
    case 23:
    break;
    case 24:
    SelectUnit->L[i] = 240;
    break;
    }

    SelectUnit->V[i] = (char *)realloc(SelectUnit->V[i], SelectUnit->L[i]+1);

    SelectUnit->T[i] = 1;
    }

    EXEC SQL WHENEVER NOT FOUND goto EndFor;

    for (;;)
    {
    EXEC SQL FETCH Cursorbase USING DESCRIPTOR SelectUnit;


    for (i=0; i < SelectUnit->F; i++)
    {
    char buffer[256];

    if (i != SelectUnit->F-1)
    sprintf(buffer, "%s|", SelectUnit->V[i]);
    else sprintf(buffer, "%s|\n", SelectUnit->V[i]);

    /*int length = strlen(buffer);*/

    trim(buffer);
    fputs(buffer,fpot);
    printf("#");
    }

    }

    fclose(fpot);

    EndFor:

    for (i=0; i < MAX_ITEMS; i++)
    {
    if (SelectUnit->V[i] != (char *)NULL) 
       free(SelectUnit->V[i]);
    free(SelectUnit->I[i]);
    }

    for (j=0; j < MAX_ITEMS; j++)
    {
    if (BindUnit->V[j] != (char *)NULL) 
        free(BindUnit->V[j]);
    free(BindUnit->I[j]);
    }

    /*
    sqlclu(SelectUnit);
    sqlclu(BindUnit);
    */

    EXEC SQL CLOSE Cursorbase;

    return 0;
    /*
    sqlerr:
    return -6;
    */

    }