2017-05-08 4 views
2

을 시작하는 올바른 방향으로 "지적해야"하고 시간 내 주셔서 감사합니다. 미리 C 프로그래밍 및 스택 오버플로 게시에 익숙하지 않다는 사과를드립니다. 내가 남겨 놓은 정보와 질문이 있으시면 언제든지 물어보십시오.C 프로그래밍

나는이 수업을 위해 수업을 진행하고 있으며 두려운 포인터가 어떻게 작동하는지 이해하는 데 어려움을 겪고 있습니다. 먼저 실험실 지침을 설명 할 것입니다.

먼저 null에 대해 최대 길이가 30 + 1 인 200 단어의 배열을 만듭니다. 다음은 작성해야하는 호출 함수입니다.

  1. 파일에서 단어를 배열로 읽는 읽기 기능입니다. fopen 및 fscanf 함수를 사용해야합니다.
  2. 각 문자의 ASCII 코드를 사용하여 문자열을 소문자로 변환하는 기능입니다. (포인터를 사용해야 함)
  3. 문자열의 길이를 반환하는 함수 (strlen 함수를 사용할 수없고 포인터를 사용해야 함)
  4. 세 개의 매개 변수 (단어 배열, 배열에있는 단어 수 및 int 길이). 함수는 int 길이와 일치하는 배열의 숫자 단어를 반환합니다.
  5. 배열의 모든 단어를 인쇄하는 인쇄 기능.

내가 사용하는 IDE는 Dev C++이기 때문에 그저 워킨 이었기 때문에 netbeans도 사용했습니다. 나는 소문자로 읽기, 인쇄 및 변환을 시도했다. 나는 먼저 파일을 읽고 메인에서 배열을 인쇄하려고했다.

  • 내부 작업 소문자 루프

편집 - 현재까지의 주요 코드를 업데이트 여기에 너무 많은 단어가 있습니다 : 나는 날에 의해 생성 읽고 있어요 파일은 정확히 다음과 짧은 문장을 포함 본관.

#define rows 200 //How many words allowed in array. 
#define cols 31  //How many characters allowed for each word. 

void lowercase(char* words, int count); 
int read(char (*words)[cols]); 
void print(char (*words)[31], int count); 

int main(int argc, char *argv[]){ 
    char words[rows][cols]; 
    int i, j; 
    int count = read(words); 

    print(words, count); 
/* 
    //make words lowercase 
    for(i = 0;i<count;i++){ 
     for(j = 0;j<cols;j++){ 
      if(words[i][j]!=0){ 
       if(words[i][j]<91 && words[i][0]>64) 
        words[i][j] = words[i][j]+32; 
      } 
     } 
    }*/ 

    for(i = 0;i < count;i++){ 
     lowercase(*words+i, count); 
    } 
    print(words, count); 

    return 0; 
} 

코드는 잘못 작성된 난 그냥 다음이 더 적합 할 것이다 첫번째 작업 할 모든 것을 얻으려고 제대로 관리됩니다. 최초의 printf 출력이 나온다 어떻게해야 :

어레이 [0]가

배열 [1] :지는

배열 [2] 그래서

배열 [3] : MANY

배열 [4] 즉

배열 [5]에

ARRA y [6] : 여기

다음 인쇄 기능을 제대로 배열에서 단어를 인쇄 할 있지만 단어 대신 각 단어의 모든 30 공백이 포함됩니다. 이것은 그것이 쓰여지는 방식으로 변경해야합니다.

void print(void *array, int SIZE){ 
    int i, 
     j; 

    char *charArray = (char *) array; 

    for(j = 0; j < SIZE; j++){ 
     for(i = 0; i < SIZE; i ++){ 
      printf("%c ", charArray[j*SIZE + i]); 
     } 
     printf("\n"); 
    } 
} 

는 I 부분적 소문자로 각 단어의 첫 문자를 변환하는 작업을 생성 하였다 ToLower 함수.이제 그것은 파산되었고 내가 무엇을 바꿨는지 기억하지 못합니다.

EDIT- 업데이트 된 소문자 기능. 메인의 소문자는 정확하게 작동하지만이 함수를 사용하면 모든 단어를 소문자로 변환하지 않고 나머지 단어가 같은 세 번째 단어에서 멈 춥니 다.

void lowercase(char *words, int count){ 
    int j; 

    for(j = 0;j<cols;j++){ 
     if(words[j]!=0){ 
      if(words[j]<91 && words[j]>64) 
       words[j] = words[j]+32; 
     } 
    } 
} 

나는 포인터와 인쇄 코드를 모방하려고도 자신의 기능에 주에 읽기 코드를 이동하려고하지만 난이 프로그램을 실행할 때 그것은 포장 마차과 exe 파일이 창을 작업하는 명령 프롬프트와 팝업을 중지 . IDE에 오류나 경고가 없습니다.

int read(void *array){ 
    FILE *file; 
    int i, 
     j; 

    char *words = (char *) array; 
    file = fopen("words.txt", "r"); 
    //STORE IN ARRAY 
    for(i=0;i<7;i++) 
     fscanf(file,"%s", words[i]); 
} 

내가 알지 못하는 경우 포인터 나 주소를 언제 어떻게 사용하는지 잘 모릅니다. 나는 기본적으로 C의 모든 것을 문자 그대로 12 시간 동안 가르쳤다. 내 의견으로는이 언어를 배우는 충분한 시간이 아니라, 특히 그것을 효율적으로 이해한다. 어떤 도움이라도 대단히 감사하겠습니다. 고맙습니다.

+0

'무효 *'대신에 '문자 워드 [] [31]를 사용하는 이유,'또는'문자 (* 단어) [31]; – BLUEPIXY

+0

나는 재미있어하려고하지는 않지만이 비디오는 훌륭합니다. 더 잘 이해할 수 있도록 도와주었습니다. https://www.youtube.com/watch?v=mnXkiAKbUPg –

+0

@BLUEPIXY 작동 시키려면 문자를 사용하여 여러 가지 오류가 발생할 수있는 유일한 방법 인 것처럼 보였습니다. 포인터 또는 C 표시가 오류를 이해하지 못하는 것은 도움이되지 않습니다. 교수님은 배열 브래킷없이 포인터를 사용하기를 원합니다. – Cherve

답변

2

2 차원 배열을 char*으로 캐스팅하면 정보가 손실됩니다. 당신이 올바르게 단어를 읽을 경우, 메모리에, 당신의 배열은 다음과 같습니다

0   10  20  30 
|.........|.........|.........|. 
There 
ARE 
so 
MANY 
words 
in 
HERE 

컴파일러는 자동으로 배열의 처음부터 31 바이트를 상쇄 words[1]에 액세스 할 수 있습니다.

wordschar*으로 변환하면 컴파일러는 더 이상 2D 구조를 알 수 없으므로 words[1]은 이제 배열 시작 부분에서 1 바이트 만 오프셋합니다.

간단한 해결 방법은 read 기능을 재정의하는 것입니다

int read(char words[][31]) 
{ 
    FILE *file; 
    int i, j, count = 0; 
    file = fopen("words.txt", "r"); 
    for (i=0; i<7; i++) 
    { 
     count += (1 == fscanf(file, "%s", words[i])); 
    } 
    return count; 
} 

지금 컴파일러가 words[i]의 메모리 보폭의 크기가 31 개 char 값 것을 알고있다.

print

비슷한 일이 추천

void print(char words[][31], int count) 
{ 
    int i; 
    for(i = 0; i < count; i ++) 
    { 
     printf("%s\n", words[i]); 
    } 
} 
2

FIX :

#include <stdio.h> 
#include <stdlib.h> 

//Stringification 
#define S_(n) #n 
#define S(n) S_(n) 

//Information to be shared across the whole area 
#define MAX_ROWS 200 
#define MAX_WORD_LENGTH 30 
#define COLS (MAX_WORD_LENGTH + 1) 

#define DATA_FILE "words.txt" 

int read(void *array); 
void print(void *array, int rows); 

int main(void){ 
    char words[MAX_ROWS][COLS]; 
    int rows; 

    rows = read(words); 
    print(words, rows); 

    return 0; 
} 

int read(void *array){ 
    FILE *file = fopen(DATA_FILE, "r"); 
    if(file == NULL){ 
     perror("fopen:"); 
     exit(EXIT_FAILURE); 
    } 
    char *words = array; 
    int rows; 
    for(rows = 0; rows < MAX_ROWS; ++rows, words += COLS){ 
     if(fscanf(file, "%" S(MAX_WORD_LENGTH) "s", words) == EOF) 
      break; 
    } 
    fclose(file); 
    return rows; 
} 

void print(void *array, int rows){ 
    char *words = array; 
    for(int r = 0; r < rows; ++r, words += COLS){ 
     printf("Array [%d]: %s\n\n", r, words); 
    } 
} 
+0

@ M.M 실제로. 감사합니다. – BLUEPIXY

+0

글로벌 정보를 사용하는 것은 기능 독립성을 손상시키는 좋은 접근 방법이 아닙니다. – BLUEPIXY