2017-03-01 43 views
-4

我寫這顯示在問題下面的是,當我使用gets()函數,然後同時在代碼塊16.01執行代碼時獲取函數被調用,然後突然一個程序代碼塊停止工作。任何人都可以幫我解決這個問題。代碼塊已停止工作,同時使用gets函數


#include <stdio.h> 
#include <stdlib.h> 
#include <conio.h> 
#include <string.h> 
#include <math.h> 

#define PI 3.1415926535897932384626433832795 

struct elements 
{ 
    float A, L, x1, y1, x2, y2; 
    double deg, c, s, E, esm[4][4]; 
    int n1, n2; 
} * ele; 

int nonod, noele; 
void elestiffmat(int); 

void main() 
{ 
    int i; 
    char ch; 
    printf("\nEnter the number of nodes you want to create:"); 
    scanf("%d", &nonod); 
    printf("\nEnter the number of elements you want to create:"); 
    scanf("%d", &noele); 
    if (noele < (nonod - 1)) 
    { 
     printf("\nThe problem is wrongly modeled.\nPress any key to abort."); 
     getch(); 
     exit(0); 
    } 
    ele = (struct elements*)malloc(noele * sizeof(struct elements)); 
    for (i = 0; i < noele; i++) 
    { 
     printf("\nCreating element %d", i + 1); 
     printf("\nCross sectional area?"); 
     scanf("%f", &ele[i].A); 
     printf("\nYoung's Modulus?"); 
     scanf("%Lf", &ele[i].E); 
     printf("\nStarting node number?"); 
     scanf("%d", &ele[i].n1); 
     printf("\nIts coordinates:"); 
     scanf("%f%f", &ele[i].x1, &ele[i].y1); 
     printf("\nEnding node number?"); 
     scanf("%d", &ele[i].n2); 
     printf("\nIts coordinates:"); 
     scanf("%f%f", &ele[i].x2, &ele[i].y2); 
     ele[i].L = sqrt(pow((ele[i].x2 - ele[i].x1), 2) + pow((ele[i].y2 - ele[i].y1), 2)); 
     if ((ele[i].x2) - (ele[i].x1) == 0) 
     { 
      if (ele[i].y2 > ele[i].y1) 
      { 
       ele[i].deg = PI/2.0; 
      } 
      if (ele[i].y2 < ele[i].y1) 
      { 
       ele[i].deg = (3.0 * PI)/2.0; 
      } 
     } 
     if ((ele[i].y2) - (ele[i].y1) == 0) 
     { 
      if (ele[i].x2 > ele[i].x1) 
      { 
       ele[i].deg = 0.0; 
      } 
      if (ele[i].x2 < ele[i].x1) 
      { 
       ele[i].deg = PI; 
      } 
     } 
     if (((ele[i].y2) - (ele[i].y1))/((ele[i].x2) - (ele[i].x1)) < 0) 
     { 
      ele[i].deg = PI + atanf(((ele[i].y2) - (ele[i].y1))/((ele[i].x2) - (ele[i].x1))); 
     } 
     if (((ele[i].y2) - (ele[i].y1))/((ele[i].x2) - (ele[i].x1)) > 0) 
     { 
      ele[i].deg = atanf(((ele[i].y2) - (ele[i].y1))/((ele[i].x2) - (ele[i].x1))); 
     } 
     // printf("%g",ele[i].deg); 
     ele[i].c = cos(ele[i].deg); 
     ele[i].s = sin(ele[i].deg); 
     // printf("c=%g\ts=%g",ele[i].c,ele[i].s); 
     elestiffmat(i); 
    } 
    getch(); 
} 
void elestiffmat(int i) 
{ 
    char choice; 
    ele[i].esm[0][0] = ele[i].c * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[0][1] = ele[i].s * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[0][2] = -ele[i].c * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[0][3] = -ele[i].s * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[1][0] = ele[i].s * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[1][1] = ele[i].s * ele[i].s * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[1][2] = -ele[i].s * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[1][3] = -ele[i].s * ele[i].s * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[2][0] = -ele[i].c * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[2][1] = -ele[i].s * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[2][2] = ele[i].c * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[2][3] = ele[i].s * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[3][0] = -ele[i].s * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[3][1] = -ele[i].s * ele[i].s * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[3][2] = ele[i].s * ele[i].c * ele[i].A * ele[i].E/ele[i].L; 
    ele[i].esm[3][3] = ele[i].s * ele[i].s * ele[i].A * ele[i].E/ele[i].L; 
    printf("\nDo you want to print the element stiffness matrix (y/n)?"); 
    gets(choice); 
    if (choice == 'y' || choice == 'Y') 
    { 
     printf("\nThe element stiffness matrix of the element %d is:-", i + 1); 
     int j, k; 
     for (j = 0; j < 4; j++) 
     { 
      printf("\n"); 
      for (k = 0; k < 4; k++) 
      { 
       printf("%15g", ele[i].esm[j][k]); 
      } 
     } 
    } 
} 
+3

嘗試使用char數組進行選擇。當寫入一個字符串時,你的char必須採取比它能容納的更多的值....這應該顯示在我猜的警告中。 –

+6

在嘗試解決這個問題之前,*停止使用*'gets'。它是邪惡的,邪惡的,每次它被用在某個小貓死亡的地方。它被從標準庫中移除*,並且不再支持。改用['fgets'](http://en.cppreference.com/w/c/io/fgets)。其次,'gets'將'char *'作爲參數,你傳遞'char',所以在使用你不應該使用的函數之前,你不會使用它作爲記錄。我會鏈接文檔,但這可能會鼓勵您繼續使用它,最終,即使您這樣做,您也不希望這樣做。 – WhozCraig

+5

首先,***永遠不會***使用'gets'。這是一個危險的功能,自C99標準以來已經過時,並在C11標準中完全刪除。改用['fgets'](http://en.cppreference.com/w/c/io/fgets)。其次,我懷疑你的IDE停止工作,但你的程序。要解決您的問題,首先使用調試器查找程序中發生崩潰的位置,然後檢查相關變量的值。如果您仍然無法弄清楚,請告訴我們該信息(位置和變量值)。 –

回答

2

如果我重建(代碼),我得到這樣

enter image description here

警告然後,嘗試用scanf(" %c", &choice);

的%C轉換指定韓元「T自動跳過任何前導空格,所以如果有輸入流中的寄生換行符。 scanf調用會立即消耗掉它。解決該問題

一種方法是把一個空白空間的轉換說明符之前在格式字符串:

scanf(" %c", &choice); 

在格式字符串中的空白告訴scanf函數跳過空白,以及第一個非空白字符將與%c轉換說明符一起讀取。 的檢查重建,我也得到沒有任何警告


  • 每當得到()語句遇到再由用戶 (帶空格的字符串)輸入的字符將被複制到變量。
  • 如果用戶開始接受字符,並且如果出現換行符 ,則換行符不會被複制到字符串 變量(即名稱)中。
  • 後 字符複製到字符串vriable(即名稱)
  • 得到()A終止空字符自動附加使用標準輸入(Standered輸入輸出)作爲源,但它並不 包括結束換行符在得到的字符串和不 不允許指定字符串變量的最大尺寸(可以 引線緩衝區溢出)。

gets()函數沒有辦法阻止你輸入字符,所以應該避免。

我希望這充分使用。很抱歉,如果任何錯誤:)我學習者

0

我不能說爲什麼「停止工作」您的系統上,但因爲它已經已經提到的,你傳遞不正確的參數,所以不確定的行爲預期。參見以下內容,從手冊頁:

char * gets(char * s);

描述

不要使用此功能。

gets()從標準輸入讀取一行到s指向的緩衝區中,直到終止換行符或EOF,它將用 空字節('\ 0')替代。沒有檢查緩衝區超限執行 (見下面的BUGS)。

所以出現了兩個失誤,路過一個字符,而不是一個緩衝區指針,並使用得到擺在首位。該手冊進一步解釋它爲什麼如此危險的使用得到

BUGS 不要使用gets()函數。因爲不知道 事先知道數據將讀取多少個字符(012),因爲gets()將繼續存儲超過緩衝區末尾的字符,所以使用它是非常危險的。它已被用於打破 計算機安全。使用fgets()代替。

欲瞭解更多信息,請參閱CWE-242(又名 「使用固有危險 功能」)在http://cwe.mitre.org/data/definitions/242.html

簡單地說,假設你已經宣佈的選擇如下:

char choice[2]; // e.g. 'y' plus terminating null byte 

沒有任何東西阻止用戶輸入「是」或其他任何內容,這超出了緩衝區大小。

請記住,您將傳遞一個指針,並且每次將指針傳遞給緩衝區時,接收函數都應接收緩衝區大小並確保它不會越過其邊界。因爲這個函數沒有把size作爲參數,所以現在不推薦使用它(在這種情況下讀取「禁止」)。

無論如何,有很多選擇,這是一個可能的解決方案。

替換 「字符選擇」 有:

int choice, c; 

,取而代之的 「獲取(選擇)」,你可以這樣做:

while((c = getchar()) != '\n' && c != EOF) 
    /* discard */ ; 
choice = getchar(); 

注意「的getchar()相當於GETC(標準輸入)」。它實際上並不直接從鍵盤上讀取。這就是爲什麼我們在提示之前添加了while循環來放棄輸入流中未處理的數據。詳細信息請參見this answer on c-faq