zoukankan      html  css  js  c++  java
  • 工作中遇到的问题一

    概要:

        最近写一个更改SQL Server中数据的小程序,因为以前没接触到SQL Server和windows方面的工作,所以一切从从头来的,期间遇到了一些问题,现在回头看看觉得有必要记录下来,算是成长的足迹吧!

    要点:

    【没解决】ADO远程连接问题:

        最开始使用的是ADO做写的脚本程序,在本地和另一个台开发机上都没问题,不过在其他的xp和win7机器上就无法运行了。

        我通过网上资料找了半天也没得到确切的答案。

        个人猜测:在可行的机器上都安装了SQL Server的客户端,而其他机器则没有安装,所以应该需要安装SQL Server客户端来解决吧。

        不过因为时间关系,放弃了使用ADO而改用使用ODBC。

    【解决】ODBC头文件:

        原先使用ODBC时使用了MFC的核心头文件,不过后来用<windows.h>和<sql.h>/<sqlext.h>就足够了。

    【解决一半】ODBC连接问题:

        我一直使用普通连接即使用函数SQLConnect()的方法没有连接通数据库,在网上也没找到症结所在,后来改用SQLDriveConnect()来替代。

        不过还需要继续查找原因的。

    【基本解决】ODBC类型:

        再使用SQLGetData()时,需要确定数据类型,这就涉及到了SQL类型、ODBC类型和C/C++类型之间的等价转换关系了。

        之所以说是基本解决是在我的脚本程序中已经解决了,不过理解的还不深入。

    【解决】ODBC语句句柄:

        先说下我遇到的症状:我先从数据库中查找数据,然后进行跟新操作,最后还有个更新,不过运行中只有第一个查询操作好用,后面就错误。

        我找到的原因,错误提示是错误的游标状态。

        网上搜集的答案是:结果集中游标的位置最开始在第一个结果前,需要先使用SQLFetch(),不过我没犯这个错误算是提个醒吧。

        我找到的原因是:每个语句对应一个SQLHSTMT语句句柄,而我使用一个语句句柄来进行多个SQL操作就出现问题了,我后来改成一个语句放在一个函数中,这样一个SQL操作对应一个语句句柄了,就没有问题了。

    【头痛的问题】C++的输入输出流:

        我是在使用scanf()是出现【缓冲区溢出】问题,上网查了下应该是输入流问题,我也有点说不清。不过遇到scanf()和【缓冲区溢出】就算是遇到这个问题。网上的一个描述是scanf()遇到'\n'时会结束,但'\n'还在缓冲区中。

        同时在使用scanf()时VS也提示是不推荐的函数。

        解决方法一、如果是windows平台有个fflush(stdin)清除缓冲区的函数,不过该函数是windows平台独有的,不支持跨平台。

        解决方法二、自己写个读取'\n'的方法。

            void flush()
           {
                char c;
                while ((c=getchar()) != '\n'&&c!=EOF) ;
           }

    网上的问题示例:

    #include<stdio.h>
    int main()
    {
    int c;

    do
    {
      scanf("%d",&c);
      printf("%d\n", c);
    }while (c != 20);

    return 0;
    }

    PS:更多scanf()问题在后面的网摘部分

    【头痛的问题】C++的字符编码问题:

        虽然感觉对编码理解挺不错了,不过具体到函数的时候还是很头痛的。

        这里的想法是还需要再好好在原先的C++相关基础上,多研究下国际化的问题了。比如说strlen()函数等都具有宽字符版本,而且windows的unicode也需要再了解。

    小结:

        知易行难!

    摘要:

    scanf的陷阱

    scanf函数从标准输入流得到数据。以下几点需要注意:
        1、scanf的返回值表示成功读入数据的个数。何为成功读入?例如,scanf("%d%d", &a, &b); 要求读入2个十进制的整数,scanf会到输入缓冲区中寻找。如果成功找到2个整数就返回2;如果找到1个就返回1,表示只有a被成功读入;如果找完整个输入缓冲区都没有找到,就返回0,表示读入失败。

    程序如下:
    #include<stdio.h>
    int main()
    {
    int a=1,b=1;
    int ret;

    ret = scanf("%d %d",&a,&b);
    printf("a=%d b=%d\n",a,b);
    printf("ret=%d\n", ret);
    return 0;
    }
    输入2个整数:
    2 3       //输入
    a=2 b=3   //输出
    ret=2     //输出

    输入2个字符:
    a b       //输入
    a=1 b=1   //输出
    ret=0     //输出
    当然,由于没有读取出a b,在缓冲区中的a b并不会消失。

        2、scanf遇到空格、回车和Tab键都会认为输入结束。

    程序如下:
    #include<stdio.h>
    int main()
    {
    char ch1[10];

    #if 1
    scanf("%s",ch1);
    printf("%s\n", ch1);
    #else
    gets(ch1);
    printf("%s\n", ch1);
    #endif
    return 0;
    }
    输入abc de
    abc de    //输入
    abc       //输出

    将#if 1改为#if 0
    输入abc de
    abc de    //输入
    abc de    //输出

        关于scanf和gets的区别:
    scanf :当遇到回车,空格和tab键会自动在字符串后面添加'\0',但是回车,空格和tab键仍会留在输入的缓冲区中。
    gets:可接受回车键之前输入的所有字符,并用'\0'替代 '\n'.回车键不会留在输入缓冲区中。

        如果非要用scanf,可以将scanf("%s",ch1);改为scanf("%[^\n]",ch1);表示接受除了'\n'外的任何字符。但是,'\n'仍然留在缓冲区中。

        3、在用"%c"输入时,空格和“转义字符”均作为有效字符。

    例如:
    #include<stdio.h>
    int main()
    {
    char ch1[10];
    char c;

    scanf("%s",ch1);
    scanf("%c", &c);
    printf("%s\n", ch1);
    printf("%d\n", c);

    return 0;
    }
    输入abc
    abc    //输入
    abc    //输出
    10     //输出
    10即'\n'的ASCII值

        4、刷新缓冲区
        在使用scanf时,如果不及时刷新输入缓冲区,有时会出现莫名其妙的错误。

    例如:
    #include<stdio.h>
    int main()
    {
    int c;

    do
    {
      scanf("%d",&c);
      printf("%d\n", c);
    }while (c != 20);

    return 0;
    }
        程序意思是让用户输入一个整数,如果这个数不是20,就继续输入。
        当用户输入整数时,这个程序能正常工作。但是,当输入的不是数字时,程序就会死锁,不断循环输出数字。
        如何解决这个问题?这就需要用到scanf的返回值。当返回值不是1时,刷新缓冲区。

        在windows中,可以使用fflush(stdin);来刷新输入缓冲区。但是,标准C并没有定义fflush对输入缓冲区的操作:

    int fflush(FILE* stream);
    Flushes stream stream and returns zero on success or EOF on error.
    Effect undefined for input stream. fflush(NULL) flushes all output streams.
        使用fflush是个很不明智的决定(gcc不支持fflush刷新输入缓冲区)。可以自己定义一个刷新输入缓冲区的函数:
    void flush()
    {
    char c;
    while ((c=getchar()) != '\n'&&c!=EOF) ;
    }
    这样就可以解决我们之前的问题了:
    int main()
    {
    int c;

    do
    {
      if (scanf("%d",&c) != 1)
       flush();
      else
       printf("%d\n", c);
    }while (c != 20);

    return 0;
    }

  • 相关阅读:
    iOS block从零开始
    iOS 简单动画 序列帧动画
    iOS 简单动画 block动画
    IOS 简单动画 首尾式动画
    IOS 手势详解
    IOS block 循环引用的解决
    IOS GCD定时器
    IOS TextField伴随键盘移动
    IOS RunLoop面试题
    IOS RunLoop 常驻线程的实现
  • 原文地址:https://www.cnblogs.com/davidyang2415/p/2541292.html
Copyright © 2011-2022 走看看