c和c++的輸入輸出


格式輸出: 
printf(格式控制, 輸出表列);
%d 十進制數  %md m為指定的寬度 若數據位數小於m,則左端補以空格;若大於m,則按實際位數輸出
%ld 長整型數據  %mld 指定字段寬度
%o 八進制整數形式  %mo
%x 十六進制整數形式  %mx
%u unsigned型數據,它也可用%o或%x格式輸出
%c 一個字符   %mc
%s 字符串 有幾種用法
 1.%s
   printf("%s", "China");
   輸出 China
 2.%ms 控制為m列 若串長小於m, 則左補空格,大於則突破m限制,將字符串完全輸出
 3.%-ms 若串長小於m, 則右補空格(居左)
 4.%m.ns 輸出占m列,取字符串左端n個字符.這n個字符輸出在m列的右側,左補空格
 5.%-m.ns m.n同上,這n個字符輸出在m列的左側,右補空格.若n>m,則m自動取n值,保證n個字符正常輸出
%f 輸出實數(包括單.雙精度),以小數形式輸出
 1.%f 輸出全部整數部分,輸出6位小數
 2.%m.nf 指定輸出的數據共占m列,其中有n位小數.若數值長度小於m,則左端補空格
 3.%-m.nf 指定輸出的數據共占m列,其中有n位小數.若數值長度小於m,則右端補空格
%e 以指數形式輸出實數
 1.%e 不指定輸出數據所占的寬度和數字部分的小數數位,數值按規范化輸出
 2.%m.ne 和 %-m.ne 輸出占m列,n指輸出的數據的小數部分(尾數)的小數數位,-同上
%g 輸出實數,根據數值大小,自動選擇f格式或者e格式(選擇輸出寬度小的),且不輸出無意義的零
格式控制中可以包含轉義字符,如'/n' '/t' '/b' '/r'
輸出%的方法 printf("%f%%", 1.0/3) 輸出: 0.333333%


格式輸入
 

scanf(格式控制, 地址表列) sscanf
類似printf .以例程解釋
1. scanf("%3d%3d", &a, &b); //列數截取數據
   input -> 123456
   then -> a = 123  b = 456
2. scanf("%2d %*3d %2d", &a, &b) //*表示跳過列數讀取數據
   input -> 12 345 67
   then -> a = 12 b = 67
3. scanf("%d, %d", &a, &b)
   input -> 1, 4  //在格式控制中,如果有非格式說明外的字符,應該在輸入時在對應位置輸入該字符
   scanf("%d   %d", &a, &b)  //輸入時,兩數據應有不少於格式控制中的空格
   scanf("%c%c%c", &a, &b, &c)  //用%c輸入字符時,空格字符和轉義字符都作為有效字符輸入
4. %s 輸入字符串.將字符串傳送到一個字符數組中,輸入時以非空白字符開始,以第一個空白字符結束.
     字符串以串結束標志'/0'作為最后一個字符
5. * 符用以表示該輸入項讀入后不賦予相應的變量,即跳過該輸入值。 
   scanf("%d %*d %d",&a,&b);  //當輸入為:1 2 3 時,把1賦予a,2被跳過,3賦予b。
6. 在輸入數據時,遇以下情況時認為該數據結束
   (1)遇空格 或 回車 或 跳格(tab)
   (2)按指定的寬度結束. 如3列的%3d
   (3)非法輸入
7. 輸入帶空格的字符串
    scanf("%[^/n]%*c", str);
    對比如下
    #include <stdio.h>
    #include <string.h>
    int main()
    {
        char str[222];
        char c;
        scanf("%[^/n]", str);
        printf("%s", str);
        scanf("%c", &c);
        printf("%c", c);
        return 0;
    }
8. 函數 int sscanf (const char *str,const char * format,........);
sscanf()會將參數str的字符串根據參數format字符串來轉換並格式化數據。轉換后的結果存於對應的參數內。
sscanf與scanf類似,都是用於輸入的,只是scanf以stdin為輸入源,前者以固定字符串為輸入源。
    # include < stdio. h>
    int main( )
    {
          const char * s = "iios/12DDWDFF@122" ;
          char buf[ 20] ;

          sscanf ( s, "%*[^/]/%[^@]" , buf ) ;
          printf ( "%s/n" , buf ) ;

          return 0;
    }
    結果為: 12DDWDFF
9. scanf 和 sscanf 的一些特殊用法:(類似正則)
    %[a-z] 表示匹配a到z中任意字符,貪婪性(盡可能多的匹配)
    %[aB'] 匹配a、B、'中一員,貪婪性
    %[^a] 匹配非a的任意字符,貪婪性
        1. 常見用法。
          charstr[ 512] = { 0} ;
          sscanf( "123456" , "%s" , str) ;
          printf( "str=%s" , str) ;
        2. 取指定長度的字符串。如在下例中,取最大長度為4字節的字符串。
          sscanf( "123456" , "%4s" , str) ;
          printf( "str=%s" , str) ;
        3. 取到指定字符為止的字符串。如在下例中,取遇到空格為止字符串。
          sscanf( "123456abcdedf" , "%[^]" , str) ;
          printf( "str=%s" , str) ;
        4. 取僅包含指定字符集的字符串。如在下例中,取僅包含1到9和小寫字母的字符串。
          sscanf( "123456abcdedfBCDEF" , "%[1-9a-z]" , str) ;
          printf( "str=%s" , str) ;
        5. 取到指定字符集為止的字符串。如在下例中,取遇到大寫字母為止的字符串。
          sscanf( "123456abcdedfBCDEF" , "%[^A-Z]" , str) ;
          printf( "str=%s" , str) ;
    % [ ] 的用法:
    % [ ] 表示要讀入一個字符集合, 如果[ 后面第一個字符是”^”,則表示反意思。
        [ ] 內的字符串可以是1或更多字符組成。空字符集(% [ ] )是違反規定的,可導致不可預知的結果。% [ ^ ] 也是違反規定的。
    % [a-z]
        讀取在 a-z 之間的字符串,如果不在此之前則停止,如
        char s[ ] = "hello, my friend” ; // 注意: ,逗號在不 a-z之間
        sscanf( s, “%[a-z]”, string ) ; // string=hello
    %[^a-z] 
        讀取不在 a-z 之間的字符串,如果碰到a-z之間的字符則停止,如
        char s[]=" HELLOkitty” ; // 注意: ,逗號在不 a-z之間
        sscanf ( s, “% [ ^ a- z] ”, string ) ; // string=HELLO
    %*[^=] 
        前面帶 * 號表示不保存變量。跳過符合條件的字符串。
        char s[ ] = "notepad=1.0.0.1001" ;
        char szfilename [ 32] = "" ;
        int i = sscanf ( s, "%*[^=]" , szfilename ) ;
        // szfilename=NULL,因為沒保存
        int i = sscanf ( s, "%*[^=]=%s" , szfilename ) ;
        // szfilename=1.0.0.1001
    %40c 讀取40個字符
    %[^=] 
        讀取字符串直到碰到’= ’號,’^’后面可以帶更多字符, 如:
         char s[ ] = "notepad=1.0.0.1001" ;
        char szfilename [ 32] = "" ;
        int i = sscanf ( s, "%[^=]" , szfilename ) ;
        // szfilename=notepad


字符串處理函數
 

1.puts(字符數組)
   將一個字符串輸出到終端
   char str[] = {"Hello otto./n"};
   puts(str);
2.gets(字符數組)   warning: the `gets' function is dangerous and should not be used.
   從終端輸入一個字符串到字符數組,並且返回字符數組的起始地址
   gets(str);
3.strcat(字符數組1,字符數組2)
   把字符串2連接到字符串1后面,結果放在字符數組1中,並返回字符數組1的地址.
   a)字符數組1必須足夠大,以容納連接后的新字符串.
   b)連接時將字符串1后的'/n'取消,保留字符串2的'/n'
4.strcpy(字符數組1,字符數組2)
   將字符串2復制到字符數組1中去.
   a)字符數組1必須足夠大,以容納連接后的新字符串.
   b)字符數組1必須寫成數組名形式,字符數組2還可以是一個字符串常量
   c)復制時連同字符串后的'/n'一起復制到字符數組1中去
   d)不能用賦值語句將一個字符串常量或字符數組直接給一個字符數組
   e)可以用strncpy函數將字符串2中前面n個字符賦值到字符數組1中
        strncpy(str1, str2, n);  n不應大於str1的長度
5.strcmp(字符串1, 字符串2)
   對兩個字符串自左至右逐個字符相比(ASCII碼,按英文字典順序,在后面的為"大",小寫字母比大寫"大")
   返回比較結果:
     a)如果字符串1=字符串2,則函數值為0
     b)如果字符串1>字符串2,則函數值為一個正整數
     c)如果字符串1<字符串2,則函數值為一個負整數
6.strlen(字符數組)
   返回字符串的實際長度(不包括'/n')
7.strlwr(字符串)
   將字符串中大寫字母換成小寫字母
8.strupr(字符串)
   將字符串中小寫字母換成大寫字母


字符串的輸入輸出與空間分配:
 
char p[34] = "string";
gets(p);  //可以輸入
char *aa;
//gets(aa);  //不可以輸入
aa = (char*)malloc(30);
gets(aa);  //可以輸入  分配空間


getch()    getche()    getchar()
 

getche()  有返回顯示 //getch() with e(echo) 回顯

    getchar()是stdio.h中的庫函數,它的作用是從stdin流中讀入一個字符,把該字符顯示在屏幕上
    getch()和getche()是conio.h中的庫函數,從鍵盤接收字符。   
    區別在於: getchar()函數等待輸入直到按回車才結束(前提是緩沖區沒有數據),回車前的所有輸入字符都會逐個顯示在屏幕上。但只有第一個字符作為函數的返回值。getch()每次都等待用戶的輸入,因為getch()從鍵盤接收,即時的接收,並不是從stdin流中去讀取數據。

    getchar()從stdin流中讀取字符,所以第一個getchar()接受的是剛剛中斷的流隊列中即將出列的第一個字符(不限於回車符),如果流隊列不為空,執行getchar()就繼續直到把回車符也放空為止,空了之后再在執行getchar()就停下等待你的輸入了。
    getchar有一個int型的返回值.當程序調用getchar時.程序就等着用戶按鍵.用戶輸入的字符被存放在鍵盤緩沖區中.直到用戶按回車為止(回車字符也放在緩沖區中).getchar函數的返回值是用戶輸入的第一個字符的ASCII碼,如出錯返回-1,且將用戶輸入的字符回顯到屏幕.如用戶在按回車之前輸入了不止一個字符,其他字符會保留在鍵盤緩存區中,等待后續getchar調用讀取.也就是說, 后續的getchar調用不會等待用戶按鍵,而直接讀取緩沖區中的字符,直到緩沖區中的字符讀完為后,才等待用戶按鍵.
  getch與 getchar基本功能相同,差別是getch直接從鍵盤獲取鍵值,不等待用戶按回車,只要用戶按一個鍵,getch就立刻返回,getch返回值是用戶輸入的ASCII碼,出錯返回-1.輸入的字符不會回顯在屏幕上.getch函數常用於程序調試中,在調試時,在關鍵位置顯示有關的結果以待查看,然后用 getch函數暫停程序運行,當按任意鍵后程序繼續運行.


 c與正則表達式 
  標准的C和C++都不支持正則表達式,但有一些函數庫可以輔助C/C++程序員完成這一功能,其中最著名的當數Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發行版本都帶有這個函數庫。
  編譯正則表達式 
  為了提高效率,在將一個字符串與正則表達式進行比較之前,首先要用regcomp()函數對它進行編譯,將其轉化為regex_t結構:
int regcomp(regex_t *preg, const char *regex,int cflags);
  參數regex是一個字符串,它代表將要被編譯的正則表達式;參數preg指向一個聲明為regex_t的數據結構,用來保存編譯結果;參數cflags決定了正則表達式該如何被處理的細節。
  如果函數regcomp()執行成功,並且編譯結果被正確填充到preg中后,函數將返回0,任何其它的返回結果都代表有某種錯誤產生。
  匹配正則表達式 
  一旦用regcomp()函數成功地編譯了正則表達式,接下來就可以調用regexec()函數完成模式匹配:
  int regexec(const regex_t *preg,
  const char *string, size_t nmatch,
  regmatch_t pmatch[], int eflags);
  typedef struct {
  regoff_t rm_so;
  regoff_t rm_eo;
  } regmatch_t;
  參數preg指向編譯后的正則表達式,參數string是將要進行匹配的字符串,而參數nmatch和pmatch則用於把匹配結果返回給調用程序,最后一個參數eflags決定了匹配的細節。
  在調用函數regexec()進行模式匹配的過程中,可能在字符串string中會有多處與給定的正則表達式相匹配,參數pmatch就是用來保存這些匹配位置的,而參數nmatch則告訴函數regexec()最多可以把多少個匹配結果填充到pmatch數組中。當regexec()函數成功返回時,從string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第一個匹配的字符串,而從 string+pmatch[1].rm_so到string+pmatch[1].rm_eo,則是第二個匹配的字符串,依此類推。
  釋放正則表達式

  無論什么時候,當不再需要已經編譯過的正則表達式時,都應該調用函數regfree()將其釋放,以免產生內存泄漏。
void regfree(regex_t *preg);
  函數regfree()不會返回任何結果,它僅接收一個指向regex_t數據類型的指針,這是之前調用regcomp()函數所得到的編譯結果。
  如果在程序中針對同一個regex_t結構調用了多次regcomp()函數,POSIX標准並沒有規定是否每次都必須調用regfree()函數進行釋放,但建議每次調用regcomp()函數對正則表達式進行編譯后都調用一次regfree()函數,以盡早釋放占用的存儲空間。
  報告錯誤信息 
  如果調用函數regcomp()或regexec()得到的是一個非0的返回值,則表明在對正則表達式的處理過程中出現了某種錯誤,此時可以通過調用函數regerror()得到詳細的錯誤信息。
  size_t regerror(int errcode,const regex_t *preg, char *errbuf,size_t errbuf_size);
  參數errcode是來自函數regcomp()或regexec()的錯誤代碼,而參數preg則是由函數regcomp()得到的編譯結果,其目的是把格式化消息所必須的上下文提供給regerror()函數。在執行函數regerror()時,將按照參數errbuf_size指明的最大字節數,在errbuf緩沖區中填入格式化后的錯誤信息,同時返回錯誤信息的長度。
  應用正則表達式 
  最后給出一個具體的實例,介紹如何在C語言程序中處理正則表達式。

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <regex.h>  
  4. /* 取子串的函數 */  
  5. static char* substr(const char*str,  
  6. unsigned start, unsigned end)  
  7. {  
  8.     unsigned n = end - start;  
  9.     static char stbuf[256];  
  10.     strncpy(stbuf, str + start, n);  
  11.     stbuf[n] = 0;  
  12.     return stbuf;  
  13. }  
  14. /* 主程序 */  
  15. int main(int argc, char** argv)  
  16. {  
  17.     char * pattern;  
  18.     int x, z, lno = 0, cflags = 0;  
  19.     char ebuf[128], lbuf[256];  
  20.     regex_t reg;  
  21.     regmatch_t pm[10];  
  22.     const size_t nmatch = 10;  
  23.     /* 編譯正則表達式*/  
  24.     pattern = argv[1];  
  25.     z = regcomp(?, pattern, cflags);  
  26.     if (z != 0)  
  27.     {  
  28.         regerror(z, ?, ebuf, sizeof(ebuf));  
  29.         fprintf(stderr, "%s: pattern '%s'",    ebuf, pattern);  
  30.         return 1;  
  31.     }  
  32.     /* 逐行處理輸入的數據 */  
  33.     while(fgets(lbuf, sizeof(lbuf), stdin))  
  34.     {  
  35.         ++lno;  
  36.         if ((z = strlen(lbuf)) > 0 && lbuf[z-1]    == '    ')  
  37.             lbuf[z - 1] = 0;  
  38.         /* 對每一行應用正則表達式進行匹配 */  
  39.         z = regexec(?, lbuf, nmatch, pm, 0);  
  40.         if (z == REG_NOMATCH) continue;  
  41.         else if (z != 0)  
  42.         {  
  43.             regerror(z, ?, ebuf, sizeof(ebuf));  
  44.             fprintf(stderr, "%s: regcom('%s')",    ebuf, lbuf);  
  45.             return 2;  
  46.         }  
  47.         /* 輸出處理結果 */  
  48.         for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x)  
  49.         {  
  50.             if (!x) printf("%04d: %s", lno, lbuf);  
  51.                 printf(" $%d='%s'", x, substr(lbuf, pm[x].rm_so,pm[x].rm_eo));  
  52.         }  
  53.     }  
  54.     /* 釋放正則表達式 */  
  55.     regfree(?);  
  56.     return 0;  
  57. }  
上述程序負責從命令行獲取正則表達式,然后將其運用於從標准輸入得到的每行數據,並打印出匹配結果。執行下面的命令可以編譯並執行該程序:
# gcc regexp.c -o regexp
# ./regexp 'regex[a-z]*' < regexp.c
0003: #include <regex.h>
$0='regex'
0027: regex_t reg;
$0='regex'
0054: z = regexec(?, lbuf, nmatch, pm, 0);

$0='regexec'

1.cin>>i>>j;是用空格或TAB來分隔輸入的. 如果是cin>>i;cin>>j;必須先輸入i,再回車,最后輸入j .

2.cout<<:   設 int x=30, y=300, z=1024;

           1)    cout<<x<<' '<<y<<' '<<z<<endl;  //按十進制輸出            
           2) 數字進制:使用hex、dec、oct分別控制輸出數字的十六,十,八進制
                  cout<<hex<<x<<' '<<y<<' '<<z<<endl;//x,y,z都按十六進制輸出
           3) 如何對齊:使用setw控制寬度
                  cout<<x<<setw(30)<<y<<endl;

                  //X正常輸出,而Y左邊會空出28個空格
                  默認對齊方式為右對齊,即填充字符從左開始,最后是輸出字符.
                 如果setiosflags(ios::left),則填充字符在右,輸出字符在前.
          4) 填充字符:使用setfill控制填充字符
                  cout<<x<<setfill('.')<<setiosflags(ios::left)<<setw(30)<<y<<endl;//28個空格用"."填充.
                填充時,如果實際長度比設置長度短,則按實際長度輸出.
          5) 設置精度:使用setprecision控制輸出精度
          6)如何取消對齊:
              cout<<resetiosflags(ios::left);//取消左對齊.因為對齊是針對所有輸出都有效果,而不專對最近的一個輸出.
          7)如何取消填充:
                setfill()如何取消呢?
                cout<<setfill(' '); 就可以了.
                注意: ' '之間是一個空格符. 因為setfill()也是對所有輸出有效,只要你設置了setw().
         8) 浮點控制格式:
             cout.setf(ios:: );//這也是針對所有輸出有效的.
             常用的有;
           ios::fixed固定的浮點顯示
           ios::scientific指數表示,科學記數法 
           ios::left / ios::right 左/右對齊
           ios::skipws忽略前導空白
           ios::uppercase / ios::lowercase 十六進制大/小寫輸出
           ios::showpos強制在正數前加+號
           ios::showpoint 強制顯示小數點后的無效0  
          precision(18);   //精度為18        
           例如:
     float f=2.0/3.0,f1=0.000000001,f2=-9.9;
    cout<<f<<' '<<f1<<' '<<f2<<endl;      //正常輸出 
    cout.setf(ios::showpos);              //強制在正數前加+號 
    cout<<f<<' '<<f1<<' '<<f2<<endl; 
    cout.unsetf(ios::showpos);            //取消正數前加+號 
    cout.setf(ios::showpoint);            //強制顯示小數點后的無效0 
    cout<<f<<' '<<f1<<' '<<f2<<endl; 
    cout.unsetf(ios::showpoint);          //取消顯示小數點后的無效0 
    cout.setf(ios::scientific);           //科學記數法 
    cout<<f<<' '<<f1<<' '<<f2<<endl;  
    cout.unsetf(ios::scientific);         //取消科學記數法 
    cout.setf(ios::fixed);                //按點輸出顯示 
    cout<<f<<' '<<f1<<' '<<f2<<endl; 
    cout.unsetf(ios::fixed);              //取消按點輸出顯示 
    cout.precision(18);                   //精度為18,正常為6 
    cout<<f<<' '<<f1<<' '<<f2<<endl; 
    cout.precision(6);                    //精度恢復為6

操縱算子實現同樣的功能:如下:

float f=2.0/3.0,f1=0.000000001,f2=-9.9;

    cout<<f<<' '<<f1<<' '<<f2<<endl;      //正常輸出

    cout<<setiosflags(ios::showpos);      //強制在正數前加+號

    cout<<f<<' '<<f1<<' '<<f2<<endl;

    cout<<resetiosflags(ios::showpos);    //取消正數前加+號

    cout<<setiosflags(ios::showpoint);    //強制顯示小數點后的無效0

    cout<<f<<' '<<f1<<' '<<f2<<endl;

    cout<<resetiosflags(ios::showpoint);  //取消顯示小數點后的無效0

    cout<<setiosflags(ios::scientific);   //科學記數法

    cout<<f<<' '<<f1<<' '<<f2<<endl;  

    cout<<resetiosflags(ios::scientific); //取消科學記數法

    cout<<setiosflags(ios::fixed);        //按點輸出顯示

    cout<<f<<' '<<f1<<' '<<f2<<endl;

    cout<<resetiosflags(ios::fixed);       //取消按點輸出顯示

    cout<<setprecision(18);               //精度為18,正常為6

    cout<<f<<' '<<f1<<' '<<f2<<endl;

    cout<<setprecision(6);                //精度恢復為6

9) 其它的輸出方法:

還有些為了讓緩沖區不影響程序的正確操作的緩沖去的操作,如:cin.putback(),fflush(stdin),cout.flush().我們

做一下簡單的說明。

    1、getch()和getche(),非緩沖式輸入,從鍵盤讀入一個字符。getch()讀入字符不顯示。有conio.h支持。

    2、cin.get(),getchar(),緩沖式輸入,從鍵盤讀入一個字符,並顯示。getchar()由stdio.h支持,cin.get()由iostream.h支持。

    3、putch()和putchar(),非緩沖式輸出,輸出一個字符到顯示器。putch()由conio.h支持,putchar()由stdio.h支持。

    4、cout.put(),緩沖式輸出,輸出一個字符到顯示器。由iostream.h支持。

    5、gets()和cin.geline(),緩沖式輸入,讀入一字符串(包括空格,不包括最后的回車),gets()由stdio.h支持,cin.getline()由iostream.h支持。

    6、puts(),非緩沖輸出,輸出一個字符串,由stdio.h支持。

    7、cin.putback(),把一個字符送回輸入緩沖區。

    8、fflush(stdin),清除輸入緩沖區操作。無法清除cin.get()等帶來的操作。

    9、cout.flush(),清楚輸出緩沖區。



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com