天天看點

c語言中重要函數

gets函數,從标準輸入讀取一行文本,一行輸入由一串字元組成,以一個換行符結尾;

gets函數丢棄換行符,并在該行的末尾存儲一個NUL字元(類似‘\0’), 然後傳回一個非NULL值。

當gets函數被調用但事實上不存在輸入行時,它傳回NULL值。

注意點:給字元串配置設定空間加NUL的空間;

格式字元串包含格式指定符(格式代碼)以及普通字元,這些普通字元将按照原樣列印出來;

但每個格式指定符将使後續參數的值按照它所指定的格式列印。

%d  十進制列印;   %g  列印浮點值;

%o  八進制列印;     %c   列印一個字元;

%x  十六進制列印;  %s  列印一個字元串;

scanf()函數傳回值是函數成功轉換并存儲于參數中的值個數;

perror函數以一種簡單、統一的方式報告錯誤,perror函數簡化向使用者報告這些特定錯誤的過程,它的原型定義于stdio.h

void perror(char  const  *message);

如果message不是NULL并且指向一個非空的字元串。perror函數就列印出這個字元串,後面跟一個分号和一個空格。

然後列印出一條用于解釋errno目前錯誤代碼的資訊;

終止執行:

exit函數,用于終止一個程式的執行,它的原型定義于stdlib.h

void  exit(int  status);

該函數的傳回值為void;

就c程式而言,所有的I/O操作隻是簡單地從程式移進或移出位元組的事情。 是以,毫不驚奇的是,這種位元組流便稱為流(stream);

程式隻需要關心建立正确的輸出位元組資料,以及正确地解釋從輸入讀取的位元組資料,特定I/0裝置的細節對程式員是隐藏;

流分為兩種類型:文本(text)流 和二進制(binary)流;

stdio.h所包含的聲明之一就是FILE結構。請不要把它和存儲于磁盤上的資料檔案相混淆。

FILE是一個資料結構,用于通路一個流,如果你同時激活量幾個流,每個流都有一個相應的FILE與它關聯,為了流上執行一些操作,你調用一些

合适的函數,并向它們傳遞一個與這個流相關聯的FILE參數;

 EOF: end of file , 它的實際值比一個字元要多幾位,這是為了避免二進制值被錯誤地解釋為EOF;

I/O函數以三種基本的形式處理資料:單個資料、文本行、二進制資料;

對于每種形式,都有一組特定的函數對它們進行處理。

  資料類型    輸入    輸出    描述

  字元      getchar   putchar   讀取(寫入)單個字元

  文本行       gets    puts    文本行未格式化的輸入(輸出)

          scanf   printf    格式化的輸入(輸出)

  二進制資料   fread   fwrite    讀取(寫入)二進制資料

字元I/O宏

  fgetc 和 fputc 是真正的函數,但getc、putc、getchar 和putchar 都是通過#define 指令定義的宏;

撤銷字元I/O

  int ungetc(int character,   FILE*  stream);

  功能:ungetc 把 一個先前讀入的字元傳回到流中,這樣它可以在以後被重新讀入;

(應用:假如你必須從一個流中逐個讀入一串數字,由于在實際讀入之前,你無法知道下一個字元,你必須連續讀取,直到讀入一個非數字字元,

  但是如果你不希望丢棄這個字元,那麼你該怎麼辦?

  使用ungetc把讀入的字元退還給流,是一個不錯的辦法)

  “退回”字元和流的目前位置有關,是以如果 用 fseek、 fsetpos、 rewind 函數改變了流的位置, 所有退回的字元都将被丢棄;

scanf家族:

  scanf函數家族的原型如下所示,每個原型中的省略号表示一個可變長度的指針清單;

從輸入轉換而來的值逐個存儲到這些指針參數所指向的記憶體位置;

  int  fscanf(FILE *stream,  char const  *format,  ... );

  int scanf(          char const *format,  ... );

  int  sscanf(char  const *string,  char  const * format,  ... );

這些函數都從輸入源讀取字元串并根據format字元串的格式代碼對它們進行轉換。

  fscanf的輸入源  就是作為參數給出的流。

 scanf從标準輸入讀取,

sscanf從第1個參數所給出的字元串中讀取字元;

  對于scanf函數的參數前面為什麼要加一個&符号?由于c的傳值參數傳遞機制,把一個記憶體位置作為參數傳遞給函數的唯一方法是傳遞一個指向該位置的指針; 在使用scanf函數時,一個非常容易出現的錯誤是忘記加&符,省略這個符号将導緻變量的值作為參數傳遞給函數,

   而scanf函數(或者其它兩個)卻把它解釋為一個指針,當它被解引用時,要麼導緻程式終止(試圖修改非法的位址);要麼導緻一個不可預測的記憶體位置的資料被修改;

   sscanf函數說明:int  sscanf(const char  *str,  const  char * format,  .......);

  sscanf()會将參數str的字元串(一定要是字元串), 根據參數format來轉換并将格式化資料,轉換後的結果存于對應的參數内;

傳回值: 成功則傳回參數數目, 失敗則傳回-1;錯誤原因存于errno中。傳回0表示失敗,否則,表示正确格式化資料的個數。

  例如:sscanf(str ,   "%d %d %s",  &i, &i2,  &s);  如果三個均成功傳回3, 如果隻讀入了第一個整數到i則會傳回1,證明無法從str讀入第二個整數;

char input[] = "10.10.aaaaaa.bbbbbb";

sscanf(input,  "%d.%d.%5[a-z] %*s %f”,&i,&j,s,s);

printf(“%d %d %s ”,i,j,s);

執行: 10 10 aaaaa

  常見用法:

    char  str[512] = {0};

    sscanf("123456", "%s", str);

    printf("str=%s", str);

    2.取指定長度的字元串。如下:

       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);

***************************************************************

  可以用如下代碼将字元串形式的ip位址轉換為四個整數:

char * inputIp  

int ip[4];  

sscanf_s(inputIp, "%d.%d.%d.%d", &ip[0], &ip[1],&ip[2],&ip[3]);  

以下部分還沒用到:  

注意sscanf_s,當讀入的類型是整數或其它長度可以确定的類型時,不能在類型後面跟上長度,但是對于字元串類型(char *)長度無法得知則必須在類型後面明确指出字元串的最大長度(即可以容納的空間)。舉例如下:  

對于多個字元串讀入的情況,代碼如下:

sscanf_s(inputString, "%s.%s.%s.%s", s1, s1.length, s2, s2.length, s3, s3.length, s4, s4.length);  

 

繼續閱讀