天天看點

校實驗室 軟體班 拓展題1istream::getline

命題人:  卿笃軍

拓展題 系列i之科普系列(共10道題目,總分15分,結算時,将你所得的分數換算成5分制,如:得了9分就是3分):

1.編寫一段代碼,要求輸出分别“燙燙燙...”和“屯屯屯...”,并簡要說明原因。(2分)

2.c++小知識:

   (1).c++中函數的預設參數.            可以檢視: c++ primer plus 275頁.

   (2).c++中函數重載.                  可以檢視:c++ primer plus 277頁.

   (3).c++中函數模闆和函數模闆重載.    可以檢視:c++ primer plus 281,283頁.

   要求:每個小知識,寫一段代碼說明,最好簡要注釋。(2分)

3.(c語言)搜尋了解#include <string.h>頭檔案中的:strncpy(),strncmp(),strtok(),memset(),memcpy(),memcmp()

  每個函數寫一個程式發給我。(2分)

4.(c語言)搜尋了解"單指針(int *p)","指針數組(int *p[])","數組指針(即行指針)int (*p)[]"的用法。

  結合一維,二維數組,編寫相應的程式說明上述指針的使用方法。(2分)

5.(c語言)了解檔案的幾種操作方式:(3分)

  搜尋如下幾個函數的使用方法:fgets(),fputs(),fscanf(),fprintf(),fread(),fwrite(),fgetc(),fputc();

  要求:分别寫代碼說明。

6.(c++)差別一下如下幾個函數:cin, cin.get(), cin.getline(); 

   要求:編寫代碼并寫簡要說明。(1分)

7.(c語言)搜尋printf()函數,明白其傳參順序。(0.5分)

   示例:

   int a = 1;

   printf("%d,%d\n",a,++a);//輸出:2,2 (為什麼?)

8.(c語言)科普:如下程式不是死循環,解釋原因。(0.5)

   int i = 20;

   while (i > 1)

   {

      ++i;

   }

9.(c語言)論const,要求:說明下面的幾種情況都是什麼隻讀?(1分)

   const int *p1 = &a;

   int const *p2 = &a;

   int *const p3 = &a;

   const int *const p4 = &a;

10.(c語言)搜尋了解main()函數中兩個參數都是什麼意思?要求:簡單說明。(1分)

#include "stdafx.h"

int main(int argc, char* argv[])

{

printf("hello world!\n");

return 0;

}

——————————————————————————————————————————————

這裡出現的”燙”其實是因為vs中調試器預設的字元集是mbcs,而在mbcs中0xcccc正好就是中文中的”燙”,是以就出現了我們熟悉的燙記憶體!

至于“屯”,是因為如果在堆中配置設定的記憶體,即用new 指令配置設定的,預設的值是0xcd。而0xcdcd在mbcs字元集裡正好是“屯”。

參考文章:imjustice 的學習筆記,

原型:<code>char</code><code>*</code><code>strncpy</code><code>(</code><code>char</code><code>*dest,</code><code>char</code><code>*src,size_tnum);</code>

<code>功能:将src字元串的前num個字元複制到dest中。</code>

參考文章:百度百科strncpy(),

原型:int strncmp(char *str1, char *str2, int maxlen);

功能:按位比較字元串str1,str2前maxlen位的大小,str1&gt;str2傳回1,str1==str2,傳回0,str1&lt;str2傳回-1

參考文章:百度百科strncmp(),

原型:char *strtok( char *strtoken, const char *strdelimit );

功能:分解字元串為一組字元串。s為要分解的字元串,delim為分隔符字元串。首次調用時,s指向要分解的字元串,之後再次調用要把s設成null。

原理:strtok遇到strdelimit所包含的分割符号,自動将其轉化為‘\0‘.同時tok指針指向前面的那段字元串。

for()循環下一次将調用最近的緩存指針,就是從最近的‘\0‘開始下一輪尋找。  直到尋找完,傳回null給tok,結束。

參考文章:

1.dojking‘s blog,關于strtok函數,

2.推薦文章:liuintermilan的專欄,

原型:void *memset(void *s, int ch,size_t n);

功能:将s所指向的某一塊記憶體中的前n個位元組的内容全部設定為ch指定的ascii值, 塊的大小由第三個參數指定,這個函數通常為新申請的記憶體做初始化工作, 其傳回值為指向s的指針。

提示:可以正确的用0初始化整個數組,其他初始化都會出現錯誤,詳情參見參考文章。

參考文章:百度百科,memset(),

原型:void *memcpy(void *dest, const void *src, size_t n);

功能:從源src所指的記憶體位址的起始位置開始拷貝n個位元組到目标dest所指的記憶體位址的起始位置中

參考文章:百度百科,memcpy(),

原型:int memcmp(const void *buf1, const void *buf2, unsigned int count);

功能:比較記憶體區域buf1和buf2的前count個位元組。

參考文章:百度百科,memcmp(),

注釋:二維數組的數組名其實就是一個行指針。(int (*p)[])也就是指向數組的一行。

原型:char*fgets(char*buf,intbufsize,file*stream);

參數:

*buf: 字元型指針,指向用來存儲所得資料的位址。

bufsize: 整型資料,指明存儲資料的大小。

*stream: 檔案結構體指針,将要讀取的檔案流。

功能:如果使用fgets()讀取某個檔案,第一次讀取的bufsize為5,而檔案的第一行有10個字元(算上‘\n‘),那麼讀取檔案的指針會偏移至目前讀取完的這個字元之後的位置。也就是第二次再用fgets()讀取檔案的時候,則會繼續讀取其後的字元。而,如果使用fgets()

讀取檔案的時候bufsize大于該行的字元總數加2(多出來的兩個,一個儲存檔案本身的‘\n‘換行,一個儲存字元串本身的結束辨別‘\0‘),檔案并不會繼續讀下去,僅僅隻是這一行讀取完,随後指向檔案的指針會自動偏移至下一行。

注意:上述代碼,必須首先自己在目錄下建立一個file.txt檔案,然後再裡面輸入一個字元。

參考文章:百度百科,fgets(),

原型:intfputs(const char*str,file*fp);

         str是字元型指針,可以是字元串常量,或者存放字元串的數組首位址。

         fp是檔案型指針,通過打開檔案函數fopen()獲得的。

功能:向指定的檔案寫入一個字元串(不自動寫入字元串結束标記符‘\0’)。成功寫入一個字元串後,檔案的位置指針會自動後移,函數傳回為一個非負整數;否則傳回eof(符号常量,其值為-1)。

注意:puts()不自動寫入‘\0‘,同時也不會寫入‘\n‘,下面測試一下:

參考文章:百度百科,fputs(),

原型:int  fscanf(file *stream, const char*format, [argument...]);

file *stream :檔案指針;

char *format :格式字元串;

[argument...] :輸入清單。

功能:從一個流中執行格式化輸入,fscanf遇到空格和換行時結束,注意空格時也結束。這與fgets有差別,fgets遇到空格不結束。

注意:執行上述代碼的時候需要先在目錄下面建立file.txt檔案,并在裡面輸入資料。如輸入:"qing 2014"    fscanf()讀取時以空格和換行區分開的。

參考文章:百度百科,fscanf(),

原型:int  fprintf(file  *stream, const char  *format, [argument]);

參數:同上。

功能:fprintf是c/c++中的一個格式化寫—庫函數;其作用是格式化輸出到一個流/檔案中;

參考文章:百度百科,fprintf(),

函數名:fwrite()

原型:size_tfwrite(const void* buffer,size_tsize,size_tcount,file*

stream);

注意:這個函數以二進制形式對檔案進行操作,不局限于文本檔案

傳回值:傳回實際寫入的資料塊數目

(1)buffer:是一個指針,對fwrite來說,是要擷取資料的位址;

(2)size:要寫入内容的單位元組數;

(3)count:要進行寫入size位元組的資料項的個數;

(4)stream:目标檔案指針;

(5)傳回實際寫入的資料項個數count。

功能:向檔案寫入一個資料塊。

函數名:fread()

原型:size_t fread ( void *buffer, size_t size, size_t count, file *stream)

;

參 數 :

      (1) buffer : 用于接收資料的記憶體位址

      (2)size   :  要讀寫的位元組數,機關是位元組

      (3)count : 要進行讀寫多少個size位元組的資料項,每個元素是size位元組.

      (4)stream :輸入流

傳回值 :

      實際讀取的元素個數.如果傳回值與count不相同,則可能檔案結尾或發生錯誤.

從ferror和feof擷取錯誤資訊或檢測是否到達檔案結尾.

1.百度百科,fwrite(),

2.百度百科,fread(),

原型:intfgetc(file*stream);

傳回值: 讀取到的字元。如果讀取到了檔案尾部則傳回eof.

注意:執行上述代碼的時候,需要首先建立一個"file.txt"檔案,并且輸入資料.

參考文章:百度百科,fgetc(),

原型:intfputc (int n, file *fp);

功能:将字元ch寫到檔案指針fp所指向的檔案的目前寫指針的位置。

參考文章:百度百科,fputc(),

cin:遇到空格,回車或者制表符就會結束輸入,這樣就導緻了我們不能輸入一個帶有空格的字元串。

cin.get(),cin.getline() :但是,很好,c++的這兩個函數幫我們解決了這一問題,它們都表示每次讀取一行字元串輸入。

不過,這兩個函數也有一些差別:

cin.getline()和cin.get()。這兩個函數都讀取一行輸入,直到達到換行符。然而,随後cin.getline()将丢棄換行符,而cin.get()将換行符保留在輸入序列中。

msdn中的用法:

istream&amp; getline( char* pch, int ncount, chardelim= ‘\n‘ );

istream&amp; getline( unsigned char* puch, int ncount, char delim = ‘\n‘ );

istream&amp; getline( signed char* psch, int ncount, char delim = ‘\n‘ );

        getline()函數讀取整行,它使用通過Enter鍵輸入的換行符來确定輸入結尾。要調用這種方法,可以使用cin.getline()。該函數有兩個參數。第一個參數是用來儲存輸入行的數組名稱,第二個參數是要讀取的字元數。如果這參數為20,則函數最多讀取19個字元,餘下的空間用于儲存自動在結尾處添加的空字元。getline()成員函數在讀取指定數目的字元或者遇到換行符時停止讀取。

        例如,假設要使用getline()将姓名讀入到一個包含20個元素的name數組中。可以使用這樣的函數調用:

cin.getline(name, 20);

這将把一行讀入到name數組中——如果這行包含的字元不超過19個。

getline()函數每次讀取一行。它通過換行符來确定尾部,單不儲存換行符。相反,在儲存字元串時,它用空字元(‘\0‘)來替換換行符。

get();

get( char*, int, char );

get( char&amp; );

get( streambuf&amp;, char );

        get()不讀取并丢棄換行符,而是将其留在輸入隊列中。

        例如,cin.get(name, 10); cin.get(blog, 10); 連續兩個cin.get()。就出問題了。

由于第一次調用後,換行符将留在輸入隊列中,是以第二次調用時看到的第一個字元就是換行符。是以get()認為已經達到行尾,而沒有發現任何讀取内容。

如果不借助幫助,get()将不能跨過該換行符。

        幸運的是,cin.get();不帶任何參數,可以讀取下一個字元(即使是換行符)。是以我們可以改成如下:

cin.get(name,10);

cin.get();

cin.get(blog,10);

這樣問題就得到了解決。

參考文獻:elohim‘s blog,

由上面這個例子可以看出printf()函數傳參是,從右往左開始傳參的,同時需要注意 ++i 和 i++的差別。

注意:while ()循環中i的值一直在增大,當增大到int的最大值的時候,就會溢出,變成一個負數。進而跳出while()循環。

   const int *p1 = &amp;a;           【a】

   int const *p2 = &amp;a;           【b】

   int *const p3 = &amp;a;           【c】

   const int *const p4 = &amp;a;【d】

為了友善,我們将上面的編号一下,a,b,c,d。

其實:【a】,【b】兩種寫法是一樣的,作用:都是*p1隻讀,(指針本身是變量,指向的内容隻讀)。

【c】p3隻讀。(指針本身隻讀,指向的内容是變量)。

【d】p4,*p4都是隻讀。(指針本身,和指向的内容都是隻讀)。

巧妙記憶法:const在哪個前面哪個就是隻讀,比如【a】const在*p1前面。又如【c】const在p3前面。

 int  argc  ; 

   這個東東用來表示你在指令行下輸入指令的時候,一共有多少個參數。比方說你的程式編譯後,可執行檔案是main.exe  ,直接在e盤根目錄下面。

   e:\&gt;main

   這個時候,argc的值是1   

   但是   

   e:\&gt;main qing blog    的話,argc的值是3。也就是指令名加上兩個參數,一共三個參數   

  char  *argv[]  ; 

   這個東東用來取得你所輸入的參數   

  e:\&gt;main   

   這個時候,argc的值是1,argv[0]的值是   "main"   

   e:\&gt;main qing blog 

   這個時候,argc的值是3,argc[0]的值是"main",argc[1]的值是"qing",argc[2]的值是"blog"。   (當然上面的代碼為了友善,是逆着輸出的)。

   這個東東一般用來為程式提供非常重要的資訊,如:資料檔案名,等等。   

校實驗室 軟體班 拓展題1istream::getline

參考文章:lambol_8309的專欄,

繼續閱讀