C언어- 문자열에서 수만 빼기 (함수 제공)

문자열에서 숫자를 빼는 함수가 아니라 수를 빼는 함수입니다. (ex) hello10hi20 => 10 20)

강좌가 아니라 소스를 제공하는 글이며, 사용하기 쉽게 함수화하였습니다.

#define type int 
#define string_size 100

typedef struct list {
	type size;
	type * array;
}list;
int num; // 문자형 배열의 인덱스로 사용되는 변수 
int idx; // value리스트 인덱스로 사용되는 변수 

char get_symbol(char* s, int Case) {
	switch (Case) {
	case -1: // 이전 문자 리턴 (case 0이 이루어진 후에 성립)
		return s[num - 2];
	case 0: // 현재 문자 리턴
		return s[num++];
	case 1: // 다음 문자 리턴 (case 0이 이루어진 후에 성립)
		return s[num];
	}
}

void value_processing(char*s, list* value) {
	char tmpm, tmp, tmpp; // tmp:현재 가져온 문자, tmpm: 이전 문자, tmpp: 다음 문자 
	int negative = 0; // 음수인지 확인하는 변수 

	while ((tmp = get_symbol(s, 0)) != '/') {
		tmpp = get_symbol(s, 1); // 다음 문자 
		tmpm = get_symbol(s, -1); // 이전 문자

		// 정수일 때 처리
		if ((tmp >= '0' && tmp <= '9') || (tmp == '-' && tmpp >= '0' && tmpp <= '9')) {

			// 이전이 -가 아니고 문자거나 쓰레기 값이면 리스트 size증가
			if ((tmpm<'0' || tmpm>'9') && tmpm != '-') {
				value->array = (type*)realloc(value->array, sizeof(type)*(++value->size));
				value->array[++idx] = 0;
				negative = 0;
			}

			// 음수 체크 
			if (tmp == '-') {
				negative = 1;
				// 음수가 연속으로 왔는지 체크 
				if (tmpm >= '0' && tmpm <= '9') {
					value->array = (type*)realloc(value->array, sizeof(type)*(++value->size));
					value->array[++idx] = 0;
				}
				continue;
			}

			// 음수일 때 처리
			if (negative == 1)
				value->array[idx] = 10 * value->array[idx] - (tmp - '0');

			// 양수나 0일 때 처리 
			else
				value->array[idx] = 10 * value->array[idx] + (tmp - '0');
		}

		// 문자일 때 처리 
		else
			continue;
	}
}

void store(char *s, list* value) {
	// 문자형 배열 인덱스 초기화 
	num = 0;

	// 문자 끝에 오는 널 문자 -> '/'로 바꾸기 
	s[strlen(s)] = '/';

	// 문자열에서 수만 빼서 저장
	value_processing(s, value);
}

list* init(list* value) {
	// 인덱스 변수 초기화
	num = 0; idx = -1;

	// 리스트 생성 및 초기화 
	value = (list*)malloc(sizeof(list));
	value->size = 0;
	value->array = (type*)malloc(sizeof(type));
	value->array[0] = 0;

	return value;
}

void display(list* value) {
	// 리스트 요소와 사이즈 출력 
	for (int i = 0; i < value->size; i++)
		printf("%d ", value->array[i]);
	printf("(size:%ld)\n", value->size);
}

구조체, 전역 변수 및 기호 상수 소개

list: 정수형 동적 배열 포인터와 배열의 크기인 size필드를 가진 구조체 (사용자가 지정할 필요 x)

type: 리스트 안 배열의 자료형 (int나 long을 권장함)

idx: 정수형 배열에 사용되는 인덱스 변수 (사용자가 지정할 필요 x)

num: 문자형 배열에 사용되는 인덱스 변수 (사용자가 지정할 필요 x)

string_size: 문자형 배열의 크기에 해당하는 기호 상수 (사용자 지정 상수)

함수 소개

list * init(list *포인터 변수): 리스트를 생성 및 초기화하고 리스트 포인터를 반환하는 함수

void store(char * 배열 포인터, list *포인터 변수): 문자형 배열을 받아서 리스트에 수만 저장하는 함수

void value_processing(char * 배열 포인터, list *포인터 변수) : store함수 내에서 호출하는 중심 함수

char get_symbol(char *배열 포인터, int 케이스 변수): 케이스 변수에 맞춰서 문자열에 속한 문자를 내보내는 함수

void display(list * 포인터 변수): 리스트 요소와 크기를 출력하는 함수

void free(list * 포인터 변수): 리스트 제거 함수

사용자 사용 방법

  1. 문자형 배열 선언을 합니다. 단, 크기는 string_size기호 상수를 이용합니다!
  2. list포인터 변수 선언하고 NULL로 초기화합니다.
  3. list포인터 변수=init(list포인터 변수); 를 작성해서 list포인터가 주소를 갖게 합니다.
  4. 함수 소개에 나온 함수를 사용해 자유롭게 코딩합니다. (value_processing, get_symbol은 호출x)
  5. 리스트를 재사용하려면 문자형 배열 요소를 초기화하는 것이 좋습니다.

함수 사용 예시

1. 매번 지워지는 리스트 반복 입/출력

2. 계속 이어지는 리스트 반복 입/출력

코딩 참고 자료

C언어- AtoI함수 없이 문자를 숫자로 바꿔보자!! (String->Positive or Negative Number)

https://shacoding.com/2019/07/30/c%ec%96%b8%ec%96%b4-%eb%ac%b8%ec%9e%90%eb%a5%bc-%ec%9e%85%eb%a0%a5%eb%b0%9b%ec%95%84-%ec%a0%95%ec%88%98%eb%a1%9c-%ec%89%bd%ea%b2%8c-%eb%b0%94%ea%bf%94%eb%b3%b4%ec%9e%90-string-positive-or-negative/

간단 로직 설명

문자열에서 문자를 하나씩 빼서 문자면 continue를 통해 넘어가고 정수면 양수인지 음수인지 확인.

음수는 ‘-‘문자를 기준으로 뒤에 숫자가 있으면 음수로 인식.

양수면 sum=sum*10+데이터를 취하고, 음수면 sum=sum*10-데이터를 취해서 계속 더해가는 구조 (배열 원소에 저장)

문자앞에 숫자가 오는 경우는 전혀 상관하지 않음,

숫자 앞에 문자나 쓰레기값이 오는 경우, realloc을 통해 배열의 크기가 늘리고 인덱스를 증가시켜서 데이터를 새로 저장할 구조를 취함.

문자열의 맨 마지막 문자인 ‘/’가 반환되면 함수가 종료

함수 사용 예시 텍스트 파일

Leave a Reply

Your email address will not be published. Required fields are marked *