728x90

25-2

문제1) 프로그램 사용자로부터 문자열을 입력받아서 입력 받은 문자열의 단어를 역으로 출력하는 프로그램을 작성해보자. 예를 들어서 'I am a boy'가 입력되면 다음의 출력을 보여야 한다.

 'boy a am I'

단! 문자열의 입력에 앞서 프로그램 사용자가 입력할 문자열의 최대길이 정보를 먼저 입력받기로 하자. 그리고 그 길이만큼 메모리 공간을 동적으로 할당해서 문자열을 입력받기로하자.

참고로 이문제에서는 메모리의 동적할당 이외에 문자열의 단어를 역으로 출력하라는 비교적 어려운 주젲를 여러분에게 제시하고 잇다. 이문제를 해결하는 방법은 여러가지이다. 따라서 여유를 가지고 여러분 나름의 방법을 찾아서 구현해보기 바란다.

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

int main(void){
    int n,len;
    char *str;
    scanf("%d", &n);
    getchar();
    str=(char *)malloc(sizeof(char)*(n+1));
    printf("Change the sentence. ");
    fgets(str,n+1,stdin);
    str[strlen(str)-1]=0;
    len=strlen(str);

    for(int i=len;i>0;i--){
        if(str[i]==' '){
            printf("%s ", &str[i+1]);
            str[i]=0;
        }
        
    }
    printf("%s",&str[0] );
    free(str);
    return 0;
}

나 혼자 단독으로 짜다가 안되는 부분이 있어서 결국 답지를 보고 말았다. 동적할당에서도 약간의 틀어짐이 있었기 때문이다. 일단 입력을 받을 때 \n을 없애주는 작업이 필수적인 것을 기억하자. 이것이 바로 getchar()이다.

그리고 fgets를 이용해야한다. 처음에는 모르고 gets로 입력받았다. 생각해보니 이것을 해야하는 이유가 문장이기 때문이다. 앞에서는 한 단어만 입력하면 되었기에 가능했던 일이었다. 문장은 fgets(어디에, 크기는, 입력인 stdin)을 이용하자

그리고 끝부분을 없애주기 위해서 len-1값을 0이라고 선언했다. 자동으로 \n부분이 있기 때문이다. 그리고 그 만큼 자리를 만들어 준다.

 

음 다음으로는 for문으로 거꾸로 해주는 작업이 필요하다. 이제 빈칸이 생기면 그 위에것들을 출력한다. 그리고 빈칸은 0으로 작업을 해준다. 그러면 그 뒤부터는 쭉 나올 것이다. 마지막 부분은 printf를 이용해 출력을 시켜주고 이것은 주솟값으로 탐색해준다. 메모리 할당을 위해 포인터를 이용했기 때문이다.

 

메모리할당 후에는 꼭 free로 메모리 해제를 해주어야 한다.


문제2) 프로그램 사용자로부터 정수를 입력받는다. -1이 입력될 때까지 계속해서 입력받아서, 프로그램 종료 직전에 입력 받은 정수 전부를 순서대로 출력하는 프로그램을 작성해보자. 그런데 이 문제의 핵심은 프로그램 사용자가 몇개의 정수를 입력할지 모른다는데 있다. 그래서 이 문제 해결을 위해서 힙 영역을 사용하기로 하겠다. 일단은 길이가 5인 int형 배열을 힙에 할당하자. 그리고 배열이 꽉 찰때마다 길이를 3씩 늘리기로 하자. 이 때 앞서 소개한 realloc함수를 이용하면 상대적으로 쉽게 배열의 길이를 늘릴 수 있다.

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

int main(void){
    int arrlen=5;
    int i=0;
    int * arr=(int *)malloc(sizeof(int)*arrlen);
    while(1){
        printf("숫자 입력해주세요. -1 되면 종료");
        scanf("%d", &arr[i]);
        if(arr[i]==-1){
            break;
        }
        if(arrlen==i+1){
            arrlen+=3;
            arr=(int *)realloc(arr,sizeof(int)*arrlen);
        }
        i++;
    }
    for(int j=0;j<i;j++){
        printf("%d ", arr[j]);
    }
    free(arr);
    return 0;
}

내가 만들고 싶은ㄴ대로 하다가 방향을 튼 케이스다. 할당ㄲ지는 일단 어렵지 않았는데 while 문안에서 arrlen ==i+1 이 부분을 작성하지를 못했다. 그래서 꽉 찰때 마다 하는 것을 제대로 만들지 못한 if문으로 확장을 해주었다. 이것이 문제였던 것 같다. 여기서 말하는 arrlen==i+1은 확장하기 위한 식인데 이제 배열은 한개가 작으므로 +1을 하여 비교를 해주었을 때 같다는 말은 꽉찼다는 얘기가 된다. 그래서 확장이 필요하다. 근데 여기서 길이를 3씩 늘리라고 하였는데 arrlen+=3을 하여서 기존보다 3을 늘려서 곱해주면 그만큼 메모리 할당이 되게 된다. 그리고 while 문이라서 i가 자동 증가가 되지 않으므로 별도의 식이 필요하다. while문 탈출하면 i 길이만큼 for문을 반복해주고 메모리 할당을 했으므로 해제를 해주고 종료를 하면 된다.

728x90

'C language > 열혈C 문제풀이' 카테고리의 다른 글

[C] 열혈C 문제풀이 26  (0) 2021.08.12
[C] 열혈C 문제풀이 24  (0) 2021.08.12
[C] 열혈C 문제풀이 17-1  (0) 2021.08.12
[C] 열혈C 문제풀이 16-1  (0) 2021.08.12
[C] 열혈C 문제풀이 14-1  (0) 2021.08.12
728x90

문제1) 프로그램 상에서 MYSTORY.TXT라는 이름의 파일을 생성해서 본인의 이름, 주민번호, 전화번호를 저장하는 프로그램을 작성하자. 단 저장의 형태는 다음과 같아야 한다.(#문자도 함께 저장되어야한다.)

    #이름: 윤성우

    #주민번호:900208-1012589

    #전화번호: 010-1111-2222

그리고 저장이 완료되면 메모장으로 확인이 가능해야 한다.

#include <stdio.h>

int main(void){
    FILE * fp=fopen("mystory.txt", "wt");
    fputs("#이름: 윤성우\n",fp);
    fputs("#주민번호: 920208-1012589\n",fp);
    fputs("#전화번호: 010-1111-2222\n",fp);
    fclose(fp);
    return 0;

}

이 문제는 이제 새로운 방식인 피일입출력 방식을 활용할 줄 안다면 크게 어렵지 않다. fopen을 통해서 파일을 열고 추가를 해야하므로 쓰기 형식으로 열어준다. 그리고 fputs로 넣어주면 된다. 반드시 줄바꿈을 넣어주고 fp 라는 것으로 넣어주게 된다.  필요한 것이 끝난다면 파일 닫아주기도 잊지말고 하면 어렵지 않다.


문제2) 문제1엥서 작성한 파일에 데이터를 추가하자. 추가할 데이터는 즐겨먹는 음식의 정보와 취미이다 입력의 형태는 다음과 같아야 한다.

    #즐겨먹는 음식: 짬뽕, 탕수육

    #취미: 축구

마찬가지로 추가가 완료되면 제대로 추가되었는지 메모장으로 확인해보기 바란다.

#include <stdio.h>

int main(void){
    FILE * fp=fopen("mystory.txt", "at");
    fputs("#즐겨먹는 음식: 짬뽕, 탕수육\n",fp);
    fputs("#취미: 축구\n", fp);
    fclose(fp);
    return 0;

}

이 문제는 앞의 문제와 연결되는 부분이다. 그렇기 때문에 앞문제가 제대로 텍스트 파일에 저장되었는지 확인후에 하는 것이 좋다. 그리고 이것을 출력한 뒤에도 확인한다. 단, 여러번 확인하게 될경우 계속 추가가 되는 것을 보았다. 그래서 직접 지워준 후에 원하는 방식으로 되었는지 컴파일해서 확인했다. 앞에 원리와 크게 다르지 않고 추가한다고 했으므로 wt 즉 쓰기 방식이 아닌 추가방식 at를 활용하면 된다. 그리고 파일 닫는 것 잊지 않으면 된다.


문제3) 문제 1과 2에서 생성한 파일에 저장된 정보 전체를 출력하는 프로그램을 작성하자

#include <stdio.h>

int main(void){
    char str[30];
    FILE * fp=fopen("mystory.txt", "rt");
    if(fp==NULL){
        puts("파일오픈 실패!");
        return -1;
    }
    fgets(str,sizeof(str),fp);
    printf("%s", str);
    fgets(str,sizeof(str),fp);
    printf("%s", str);
    fgets(str,sizeof(str),fp);
    printf("%s", str);
    fgets(str,sizeof(str),fp);
    printf("%s", str);
    
    fclose(fp);
    return 0;

}

앞의 문제에서는 입력 값을 넣어주었다고 보면 이제는 출력의 시간이다. 일단 문자열도 선언해주고 읽어야 하므로 read방식인 rt를 이용한다. 빈 값이면 NULL값이 있을 때를 만들어서 return을 해주게 된다. 출력의 방식은 fgets이다. 그리고 괄호안에 들어가는 것은 str문자열에 str문자열 크기만큼 fp를 넣어준다는 의미이다. 그리고 출력을 해주면 된다. 줄마다 출력을 해줘야 하므로 여러번 똑같은 코드가 반복된다. 읽기 모드에서도 닫는 것은 잊지 말자

728x90

'C language > 열혈C 문제풀이' 카테고리의 다른 글

[C] 열혈C 문제풀이 26  (0) 2021.08.12
[C] 열혈 C 문제풀이 25  (0) 2021.08.12
[C] 열혈C 문제풀이 17-1  (0) 2021.08.12
[C] 열혈C 문제풀이 16-1  (0) 2021.08.12
[C] 열혈C 문제풀이 14-1  (0) 2021.08.12
728x90

문제1) 다음과 같이 두개의 int형 포인터 변수와 길이가 5인 int형 배열을 선언한다.

int *maxPtr;

int *minPtr;

int arr[5];

 

그리고 MaxAndMin이란 이름의 함수를 정의하고 이를 호출하면서 위의 배열과 두 포인터 변수에 대한 정보를 전당ㄹ하자. 어떠한 정보를 어떻게 전달할지는 여러분이 결정할 몫이다. 그리고 함수 호출이 완료되면 포인터 변수 maxPtr에는 가장 큰 값이 저장된 배열요소의 주소 값이, inPtr에는 가장 작은 값이 저장된 배열요소의 주소 값이 저장되어야 한다.

#include <stdio.h>
void MaxAndMin(int *arr1,int len, int **maxp,int **minp){
    int *max, *min;
    max=min=&arr1[0];
    for(int i=0;i<len;i++){
        if(*max<arr1[i]){
            max=&arr1[i];
        }
        if(*min>arr1[i]){
            min=&arr1[i];
        }
    }
    *maxp=max;
    *minp=min;
}
int main(void){
    int *maxPtr;
    int *minPtr;
    int arr[5];
    for(int i=0;i<5;i++){
        scanf("%d", &arr[i]);
    }
    MaxAndMin(arr,sizeof(arr)/sizeof(int), &maxPtr, &minPtr);
    printf("%d %d", *maxPtr, *minPtr);
    return 0;
}

이건 조금 헷갈렸던 것 같다. 포인터를 써줘야 할지 말아야 할지에 대한 여부가 아직 잘 안된다. 부르는 것까지는 잘했지만 len값을 보내주는 것을 잊었다. 그리고 포인터 변수의 주소값이기 때문에 값전달시 &변수 라고 써줘야 하는 것과 또 임의로 *를 이용해서 변수를 생성해서 비교시에는 *변수 <arr[i] 이렇게 써주지만 주소값으로 저장해줄 때에는 &변수라고 되어있는 것을 =으로 받아들인다. 

또한 한번만 참조하기 때문에 maxp가 한번 참조한게 최대값과 같다는 형식으로 나아가야 한다.

 

728x90

'C language > 열혈C 문제풀이' 카테고리의 다른 글

[C] 열혈 C 문제풀이 25  (0) 2021.08.12
[C] 열혈C 문제풀이 24  (0) 2021.08.12
[C] 열혈C 문제풀이 16-1  (0) 2021.08.12
[C] 열혈C 문제풀이 14-1  (0) 2021.08.12
[C] 열혈C 문제풀이 13-1 1번,3번  (0) 2021.08.12

+ Recent posts