1. 程式人生 > >fscanf(scanf)|fgets(fgetchar)函式對於空格和回車的不同處理

fscanf(scanf)|fgets(fgetchar)函式對於空格和回車的不同處理

    有一道程式設計如下:
      #include <stdio.h>
          main()
          {int i,flag;
          char str[80],c;
          file *fp;
          fp=fopen("text","w");
          flag=1;
          while(flag==1)
          {printf("/ninput string:/n");
          gets(str);
          fprintf(fp,"%s",str);
          printf("/ncontinue?");
          c=getchar();
          if((c=='n')||(c=='n'))
          flag=0;
          getchar(); (接收回車)
          }
          fclose(fp);
fp=fopen("text","r");
while(fscanf(fp,"%s",str)!=eof)
{for(i=0;str[i]!='/0';i++)
if((str[i]>='a')&&(str[i]<='z'))
str[i]-=32;
printf("/n%s/n",str);
}
fclose(fp);
}

          執行程式時,如果輸入“abc”回車,再輸入“def”回車,會顯示結果“abcdef”,但是如果輸入的字串中包含空格,比如輸入i am a student,結果會將"i" "am" "a" "student"這4個字串分別輸出4行上.
          要弄清楚這個問題,首先要對fscanf和fgets這兩個檔案函式的概念有深入的瞭解,對於字串輸入而言這兩個函式有一個典型的區別是:
          fscanf讀到空格或者回車時會結束並返回,字串自動加‘/0’,但是而fgets函式則把空格作為字元接收。
          有這樣一個例子:
char str[13];
scanf("%s",str);
          如果輸入以下12個字元how are you?回車
          實際上並不是把這12個字元加上/0送到陣列str中,而只將空格前的“how”送到str中,由於把“how”作為一個字串處理,因此在其後加/0。
         當你敲回車時,實際輸入了兩個字元,回車(13)和換行(10),scanf遇到回車就返回,結果把一個換行符丟在了鍵盤緩衝裡,而getchar偏偏見了換行符就直接返回,所以沒有別的辦法,在getchar前面先把輸入緩衝清掉,即fflush(stdin),&<60; 如果對輸入流內的資料需要保留也可在scanf後面加一句getchar把換行符先讀掉,具體情況具體處理。

getchar,gets,見了換行符才返回,所以緩衝區沒有回車或者換行這樣的字元存在了,因此gets後面的getchar能得到正確的字元,實際上scanf的這種設計是存在一些問題的,所以才導致這些問題的出現。

我們可以將gets改為scanf,即:
#include <stdio.h>
          main()
          {int i,flag;
          char str[80],c;
          file *fp;
          fp=fopen("text","w");
          flag=1;
          while(flag==1)
          {printf("/ninput string:/n");
   scanf("%s",str);
          fprintf(fp,"%s",str);
          printf("/ncontinue?");
          c=getchar();
          if((c=='n')||(c=='n'))
          flag=0;
   getchar();
          }
          fclose(fp);
fp=fopen("text","r");
while(fscanf(fp,"%s",str)!=eof)
{for(i=0;str[i]!='/0';i++)
if((str[i]>='a')&&(str[i]<='z'))
str[i]-=32;
printf("/n%s/n",str);
}
fclose(fp);
}
這時候我們會發現,即便我們輸入n,程式依然會進行下去,原因就是scanf遇到回車符返回了,留有換行符,而第一個getchar遇到換行符返回,讀入的資料實際上被第二個getchar所接收了,因此無法結束。

          補充一個問題,如果想讓"i" "am" "a" "student"輸出在同一行上程式應該怎麼改?
          答案就是:fscanf換成fgets(fp, str) 。

再舉一例getchar()函式對空格以及回車的處理:
#include<stdio.h>
#define max 1000
main()
{int c,i,flag,flag1;
char t[max];
i=0;
flag=0;
flag1=1;
printf("/nplease input a hexadecimal number:");
while((c=getchar())!='/0'&&i<max&&flag1)
{if(c>='0'&&c<='9'||c>='a'&&c<='f'||c>='a'&&c<='f')
{flag=1;
t[i++]=c;
}
else if(flag)
{t[i]='/0';
printf("/n decimal number :%d/n",htoi(t));
printf("continue? (y/n):");
c=getchar();
if(c=='n'||c=='n')flag1=0;
else
    {flag=0;
     i=0;
     printf("/nplease input a hexadecimal number:");
    }
}
}
}
htoi(s)
char s[];
{int i,n;
n=0;
for(i=0;s[i]!='/0';i++)
{if(s[i]>='0'&&s[i]<='9')n=n*16+s[i]-'0';
if(s[i]>='a'&&s[i]<='f')n=n*16+s[i]-'a'+10;
if(s[i]>='a'&&s[i]<='f')n=n*16+s[i]-'a'+10;
}
return(n);
這道程式設計表面上看起來沒什麼,實際有一些玄妙:
第一次執行:please input a hexadecimal number:
輸入:12 回車
decimal number :18
continue? (y/n):y
please input a hexadecimal number:
這時如果輸入:ac空格 回車
會出現這樣的結果:
decimal number:172
continue? (y/n):
please input a hexadecimal number:
也就是直接跳過continue? (y/n):的條件判斷了,這不得不讓人很是奇怪,怎麼會不讓我輸入“y”或“n”來判斷呢?那麼我上面輸入:12 回車,怎麼就需要判斷了呢?
      其實這個問題也和上面的類似,輸入ac+空格後,getchar函式已經得到了空格,並且這個空格在隨後的語句中沒有得到處理,不同於ac已經在if語句中被處理t[i++]=c;那麼在continue? (y/n):這個條件判斷中,記憶體中還保留有空格,所以不進行輸入(y/n)判斷而直接繼續後面的語句。
      同樣你輸入acz這樣的字串也不會進行判斷,這時記憶體中儲存的是z,這裡以回車和空格舉例只是為了說明兩者之間的區別。

相關推薦

fscanf(scanf)|fgets(fgetchar)函式對於空格回車不同處理

    有一道程式設計如下:       #include <stdio.h>           main()           {int i,flag;           char str[80],c;           file *fp;

replaceAll替換空格回車

有這個一個任務,使用者在停保的時候降停保原因寫成加空格和回車的話,再次新申請審批的時候不能帶出資訊,所以要將停保原因中的回車符去掉,加了兩行程式碼: stopreason =stopAll.g

EditText禁止輸入空格回車

    EditText經常會禁止輸入一些字元,例如,不允許輸入空格,不允許回車。    1.不允許輸入空格,這裡我們採用對EditText新增輸入監聽://監聽輸入框禁止輸入空格 editText.addTextChangedListener(new TextWatcher

字串去除空格回車

java去除字串中的空格、回車、換行符、製表符 跳至 [1] [全屏預覽] import java.util.regex.Matcher; import java.util.regex.Pat

程式設計規範之tab設定4空格回車設定Unix(idea)

idea使用前設定好以下幾點 1.maven自動導包及倉庫位置配置檔案 2.編碼格式 3.tab**請勿勾選**Use tab character 4.空格符設定為unix格式不

轉載 -- scanffscanffgets,sscanf區別,c語言

fgets、gets、scanf函式讀入字串比較 https://blog.csdn.net/lanceleng/article/details/8730192   首先,說說這個函式的使用方法。程式碼如下: char str[10]; fgets(str, 10, std

C/C++ scanf 函式中%s %c 的簡單區別

首先宣告:在鍵盤中敲入字元後,字元會首先儲存在鍵盤緩衝區中供scanf函式讀取(scanf,getchar等函式是讀取緩衝區,getch函式是讀取的控制檯資訊,即為直接從鍵盤讀取)。另外特別注意鍵盤上敲入回車實際為“\r\n”,但儲存到緩衝區時候會捨棄‘\r’而只儲存\n

C語言 gets()scanf()函式的區別

scanf( )函式和gets( )函式都可用於輸入字串,但在功能上有區別。若想從鍵盤上輸入字串"hi hello",則應該使用__gets__函式。 gets可以接收空格;而scanf遇到空格、回車和Tab鍵都會認為輸入結束,所有它不能接收空格。 char stri

【C語言天天練(十八)】字元/字串輸入函式fgetc、fgets、getc、getchargets

#include <stdio.h> intfgetc(FILE *stream); char *fgets(char *s, int size, FILE *stream); int getc(FILE *stream); int getchar(void);

printfscanf的原函式

/* <pre name="code" class="cpp">函式名: scanf 功 能: 執行格式化輸入 用 法: <strong>int scanf(char *

c++ 去除字串中的空格標點符號 (remove_if 函式的用法)

C++中提供了自動刪除空格和標點符號的函式,使用如下: #include <ctype.h> #include <algorithm> str_testing.erase(

(1)fgets函式的理解用法

fget函式的原型如下:char *fgets(char *buf, int n, FILE *fp)功能:從檔案流讀取一行,送到緩衝區,使用時注意以下幾點:1.當遇到換行符或者緩衝區已滿,fgets就會停止,返回讀到的資料,值得注意的是不能用fgets讀二進位制檔案,因為fgets會把二進位制檔案當成文字檔

sublime text 3 顯示空格Tab

ces space setting 希望 pytho blog csdn 顯示 img 因為sublime text3確實太好用了所以也用它寫代碼了,可是在Python3中不支持Tab鍵和空格鍵混用所以要改變顯示方式,以便方便使用,突然發現網上的資料太少,所以我把它貼了出來

Python基礎課:定義一個函數,可以對序列逆序的輸出(對於列表元組可以不用考慮嵌套的情況)

int 情況 type spa list bsp pri not log 1 15 def fun(arg): 2 16 if type(arg) is not tuple 3 17 and type(arg) is not str 4 18

webpack vue-cli 一有空格分號就報錯

pac async sta 報錯 函數塊 代碼 lint 函數參數 ons webpack vue-cli 一有空格和分號就報錯 eslintrc.js 這是ESLint的配置文件,至於為什麽用ESLint的話,就是為了自動檢查代碼,保持一致的代碼風格,從而保證代碼質量.

第一天,對於課程工作的了解

family 學習 it行業 宋體 col style 感覺 喜歡 比較 今天聽這裏的老師講了很多關於it行業的事,我對於java這一方面也是比較感興趣。 對也以後的就業今天也是有了一番了解,自我感覺,我喜歡這一塊,並且有學習的想法, 我會努力的去學習這一塊,為了工

空格空白文本

join [] 去空格 repl ++ bsp box == 左右 //去所有空格   var str = " 3 2 4 43 ";   var reg = /\s+/g;   console.log(‘(‘+str.replace(reg,"")+‘)‘) //

網上整理的對於RestRestful api的理解

gpo 信息 常用 method 安全 什麽 獲取 正常 stat 一、什麽是Rest? REST不是"rest"這個單詞,而是幾個單詞縮寫 -- REpresentational State Transfer 直接翻譯:表現層狀態轉移,但這個翻譯正常人根本看不懂,找到的一

保留文本空格換行

class break body 空格 wrap pre hit clas -m .content { white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wra

【sqli-labs】 less26 GET- Error based -All you SPACES and COMMENTS belong to us(GET型基於錯誤的去除了空格註釋的註入)

src blog sci 字符 XML 包含 col concat image 看了下源碼 所有的註釋形式和反斜線,and,or都被了過濾掉了 單引號沒有過濾 空格也被過濾了 http://localhost/sqli-labs-master/Less-26/?id=