網域名稱俱樂部


返回   網域名稱俱樂部 > 電腦與網路技術 > 電腦網路相關技術 > 一般軟體與網路使用討論
論壇幫助 社區 日曆事件 今日新文章 搜尋

回覆
 
主題工具
  #1  
舊 2014-02-20, 12:00 AM
哈啦 的頭像
哈啦 哈啦 目前離線
論壇管理員
 
註冊日期: 2002-05-28
文章: 23,053
預設 C語言的字串陣列問題

照著課本抄了一個翻譯功能的字串陣列,如下:
代碼:
#include<stdio.h>
#include<string.h>

char words[][2][40] = {
        "dog", "xiao gou",
        "car", "che zi",
        "gold", "jin zi",
        "child","hai zi",
        "wife","qi zi",
        "game","you xi",
        "house","fang zi",
        "rich","fa cai",
        "",""
};

int main(void)
{
        char english[80];
        int i;
        
        printf("enter english word: \n");
        gets(english);
        
        //look up the work
        
        i=0;
        //search while null string not yet encountered.
        
        while(strcmp(words[i][0],"")) {
                if(!strcmp(english,words[i][0])) {
                        printf("chinese translation: %s", words[i][1]);
                        break;
                        i++;
                }
        }
                if(!strcmp(words[i][0],"")) printf("not in dictionary.\n");
                return 0;
        }


結果編譯沒問題,但執行時,則發生問題,也就是只有輸入第一個English的單字 dog 會輸出答案 xiao gou,如果輸入第二個以後的任何單字,則沒有反應,只剩游標在那裡一閃一閃的,也不會自動停止程式,似乎就當在那了?
不知以上的程式是哪邊出錯?

thanks.
__________________
咖啡走路
微博


您是網站站長嗎?歡迎到站長俱樂部 一起討論吧。
按我看版規
code.club
回覆時引用此篇文章
  #2  
舊 2014-02-20, 12:46 AM
a40136 a40136 目前離線
進階會員
 
註冊日期: 2007-07-01
文章: 261
預設

代碼:
#include<stdio.h>
#include<string.h>
#include <iostream>
using namespace std;
char words[][2][40] = {
        "dog", "xiao gou",
        "car", "che zi",
        "gold", "jin zi",
        "child","hai zi",
        "wife","qi zi",
        "game","you xi",
        "house","fang zi",
        "rich","fa cai",
        "",""
};

int main(void)
{
        char english[80];
        int i;

        printf("enter english word: \n");
        gets(english);

        //look up the work

        i=0;
        //search while null string not yet encountered.

        while(strcmp(words[i][0],""))
        {
                if(!strcmp(english,words[i][0]))
                {
                        printf("chinese translation: %s", words[i][1]);
                        break;
                }
                i++;
        }
        if(!strcmp(words[i][0],"")) printf("not in dictionary.\n");
        return 0;
}
i++放錯位置了,你輸入car會去比對dog,但是不符合,所以不會進if statement
所以i永遠會是0,會造成while不會中止,所已過一段時間程式就crash了。
回覆時引用此篇文章
  #3  
舊 2014-02-20, 12:56 AM
哈啦 的頭像
哈啦 哈啦 目前離線
論壇管理員
 
註冊日期: 2002-05-28
文章: 23,053
預設

引用:
作者: a40136 查看文章

i++放錯位置了,你輸入car會去比對dog,但是不符合,所以不會進if statement
所以i永遠會是0,會造成while不會中止,所已過一段時間程式就crash了。
十分感謝,果然是如此

原本課本裡的這道範例,漏了幾個符號,其中一個就是少了},我編譯時除錯發現了,就增加一個},但沒想到還是放錯位置,應放在i++的前面。

這裡真是高手如雲,很多版友其實都深藏不露
__________________
咖啡走路
微博


您是網站站長嗎?歡迎到站長俱樂部 一起討論吧。
按我看版規
code.club
回覆時引用此篇文章
  #4  
舊 2014-02-21, 03:05 PM
哈啦 的頭像
哈啦 哈啦 目前離線
論壇管理員
 
註冊日期: 2002-05-28
文章: 23,053
預設

請看一下這個陣列程式:

#include <stdio.h>

int main(void)
{

char text[][80] = {
"when","in","the","course","of","human","events","",};

int i,j;

//now display them.

for(i=0;text[i][0];i++)
{
for(j=0;text[i][j];j++)
printf("%c",text[i][j]);
printf("\n");
}
return 0;
}

請問一下,為何for的迴圈條件中,這紅字部份是啥用意?
再者,中間的條件式可以用這樣的陣列嗎?

thanks
__________________
咖啡走路
微博


您是網站站長嗎?歡迎到站長俱樂部 一起討論吧。
按我看版規
code.club
回覆時引用此篇文章
  #5  
舊 2014-02-21, 03:43 PM
a40136 a40136 目前離線
進階會員
 
註冊日期: 2007-07-01
文章: 261
預設

for的第2個col是代表終止條件,只要這個arr還有值就會繼續執行下
回覆時引用此篇文章
  #6  
舊 2014-02-21, 03:58 PM
哈啦 的頭像
哈啦 哈啦 目前離線
論壇管理員
 
註冊日期: 2002-05-28
文章: 23,053
預設

引用:
作者: a40136 查看文章
for的第2個col是代表終止條件,只要這個arr還有值就會繼續執行下
就本題來說有點懂了 many thanks
__________________
咖啡走路
微博


您是網站站長嗎?歡迎到站長俱樂部 一起討論吧。
按我看版規
code.club
回覆時引用此篇文章
  #7  
舊 2014-02-21, 05:30 PM
哈啦 的頭像
哈啦 哈啦 目前離線
論壇管理員
 
註冊日期: 2002-05-28
文章: 23,053
預設

以下有個習題,是要使用者打一個阿拉伯數字,然後會顯示該數字相對應的英文單字,僅限從0到9而已。
我自己先寫了一個如下:
代碼:
#include <stdio.h>

int main(void)
{
	int x;
	char digits[][10]={
	"zero","one","two","three","four","five","six","seven","eight","nine"};
	
	printf("enter a number: \n");
	scanf("%d",&x);
	
	printf("%s", digits[x]);
	
	return 0;
}
而書上的解答則是如下:
代碼:
#include <stdio.h>
#include <conio.h>

int main(void)
{
	char digits[10][10] = {
		"zero","one","two","three","four","five","six","seven","eight","nine"};
		char num;
		
		printf("enter a number: ");
		num=getche();
		printf("\n");
		
		num=num-'0';
		if(num>=0 && num<10) printf("%s",digits[num]);
		
		return 0;
	}
就運作來看,二者都正常,且獲得同樣的結果。但由於我的方式和解答有很大不同,不知各位先進能否幫我看看,我的寫法是否有什麼看不見的漏洞?
而且書上提示說:只要將使用者輸入的數字字元減掉字元'0',便可獲得相對應的索引值,這是什麼意思?
還有,前一題中的字串陣列中char text[][80] = {
"when","in","the","course","of","human","events","",}; 為何要在最後加一個" " ?這有何用意嗎?

thanks
__________________
咖啡走路
微博


您是網站站長嗎?歡迎到站長俱樂部 一起討論吧。
按我看版規
code.club
回覆時引用此篇文章
  #8  
舊 2014-02-22, 01:05 AM
a40136 a40136 目前離線
進階會員
 
註冊日期: 2007-07-01
文章: 261
預設

引用:
作者: 哈啦 查看文章
以下有個習題,是要使用者打一個阿拉伯數字,然後會顯示該數字相對應的英文單字,僅限從0到9而已。
我自己先寫了一個如下:
代碼:
#include <stdio.h>

int main(void)
{
	int x;
	char digits[][10]={
	"zero","one","two","three","four","five","six","seven","eight","nine"};
	
	printf("enter a number: \n");
	scanf("%d",&x);
	
	printf("%s", digits[x]);
	
	return 0;
}
而書上的解答則是如下:
代碼:
#include <stdio.h>
#include <conio.h>

int main(void)
{
	char digits[10][10] = {
		"zero","one","two","three","four","five","six","seven","eight","nine"};
		char num;
		
		printf("enter a number: ");
		num=getche();
		printf("\n");
		
		num=num-'0';
		if(num>=0 && num<10) printf("%s",digits[num]);
		
		return 0;
	}
就運作來看,二者都正常,且獲得同樣的結果。但由於我的方式和解答有很大不同,不知各位先進能否幫我看看,我的寫法是否有什麼看不見的漏洞?
而且書上提示說:只要將使用者輸入的數字字元減掉字元'0',便可獲得相對應的索引值,這是什麼意思?
還有,前一題中的字串陣列中char text[][80] = {
"when","in","the","course","of","human","events","",}; 為何要在最後加一個" " ?這有何用意嗎?

thanks
哈大:

書上是用getchar以及char去存使用者Input,是用ASCII去存,所以拿使用者輸出去減 '0' (注意這裡是指字元而非整數),就會取得差也就會是轉成整數了。

您的寫法要注意一點是您無法預估使用者會不會搗蛋,輸入超過臨界<1 >10的值而導致程式產生不可預期的狀態,範例就有輸入num做檢驗(num>=0 && num<10),這方面是比較好的做法,"永遠"不要相信使用者的輸入。

最後您所提到的方法我很少使用,我猜是各種Compiler針對arr的空控制條件不同,為使得不要產生undefined的狀況,所以故意弄一個"",確保最後一定是空值。

C/C++存在許多undefined的條件(像是除0、Out of bound),使用g++、GCC編譯加入 -O-、-O2實有時會有意外的結果產生。
回覆時引用此篇文章
  #9  
舊 2014-02-22, 01:30 AM
哈啦 的頭像
哈啦 哈啦 目前離線
論壇管理員
 
註冊日期: 2002-05-28
文章: 23,053
預設

引用:
作者: a40136 查看文章
哈大:

書上是用getchar以及char去存使用者Input,是用ASCII去存,所以拿使用者輸出去減 '0' (注意這裡是指字元而非整數),就會取得差也就會是轉成整數了。

您的寫法要注意一點是您無法預估使用者會不會搗蛋,輸入超過臨界<1 >10的值而導致程式產生不可預期的狀態,範例就有輸入num做檢驗(num>=0 && num<10),這方面是比較好的做法,"永遠"不要相信使用者的輸入。
了解,剛才我再測試一下我的寫法,果然在某些情況下會出錯。例如我輸入1000000就會當掉,或者輸入a or ccc or g等非數字,結果全得到zero的結果。

而書上的範例則只容許0 to 9,沒有機會讓你打出10以上的數字,若打非數字則不顯示結果,但依然return 0,不會當掉。

看來我還是得再研究一下書本範例的邏輯推演,依我自己的直覺的邏輯推出來的確實有誤。十分感謝。

但拿使用者輸出去減 '0',這一點我還是搞不懂why doing so?
__________________
咖啡走路
微博


您是網站站長嗎?歡迎到站長俱樂部 一起討論吧。
按我看版規
code.club
回覆時引用此篇文章
  #10  
舊 2014-02-22, 01:37 AM
a40136 a40136 目前離線
進階會員
 
註冊日期: 2007-07-01
文章: 261
預設

引用:
作者: 哈啦 查看文章
了解,剛才我再測試一下我的寫法,果然在某些情況下會出錯。例如我輸入1000000就會當掉,或者輸入a or ccc or g等非數字,結果全得到zero的結果。

而書上的範例則只容許0 to 9,沒有機會讓你打出10以上的數字,若打非數字則不顯示結果,但依然return 0,不會當掉。

看來我還是得再研究一下書本範例的邏輯推演,依我自己的直覺的邏輯推出來的確實有誤。十分感謝。

但拿使用者輸出去減 '0',這一點我還是搞不懂why doing so?
char 存0 是存48,存1是49,所以拿 '1'(這裡是字元)-'0' = 49-48 = 1

ASCII對照表如下請參考


另外要注意您宣告的interger沒特別註記的話會 signed interger
界線通常是-32767~32767,所以輸入1000000當然會當掉,是
很合理的,再來您輸入非數字卻存入int這是"非常"危險的事情,會
造成overflow,有機會會多寫入幾個byte汙染到連續記憶體區段
後面的空間(這是undefined behavior看各compiler如何處理)。

此篇文章於 2014-02-22 01:47 AM 被 a40136 編輯。
回覆時引用此篇文章
回覆


發文規則
不可以發表新主題
不可以發表回覆
不可以上傳附件
不可以編輯自己的文章

啟用 BB 代碼
論壇啟用 表情符號
論壇啟用 [IMG] 代碼
論壇禁用 HTML 代碼



所有時間均為 +8。現在的時間是 06:45 AM


本站主機由網易虛擬主機代管
Powered by vBulletin® 版本 3.8.4
版權所有 ©2000 - 2024,Jelsoft Enterprises Ltd.