2010-03-03 2 views
9

미리 고정 된 크기의 배열을 할당하지 않고 C로 문자열을 읽을 수 있습니까?미리 할당 된 고정 길이 버퍼에 넣지 않고 C에서 알 수없는 크기의 문자열을 읽을 수 있습니까?

매번 고정 크기의 문자 배열을 선언 할 때마다 틀리게 생각합니다. 나는 항상 내 유스 케이스에 대해 최대라고 생각하는 것을 추측하고있다. 그러나 이것이 항상 쉬운 것은 아니다.

또한 더 큰 컨테이너에 작은 문자열을 배치하는 아이디어가 마음에 들지 않습니다. 그것은 기분이 좋지 않습니다.

내가 누락 된 항목이 있습니까? 이 일을해야하는 다른 방법이 있습니까?

+0

논리적으로 생각하면, 어떤 종류의 버퍼에 저장되지 않았다면 문자열로 무엇을 할 것입니까? 입력 스트림의 일부분을 읽어 들인 다음 작은 버퍼와 동일한 블록으로 다시 할당되는 백엔드 저장소로 전달하는 작은 버퍼를 가질 수는 있지만 가장 효율적인 프로세스는 아닙니다. – Lazarus

+0

나는이 페이지, 특히이 섹션을 읽을 필요가 있다고 생각한다. http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize –

답변

3

"ahead of time"이라고 말하면 런타임시 또는 컴파일시를 의미합니까? 컴파일시에 이 작업을 수행 : 런타임에

char str[1000]; 

당신은이 작업을 수행 :

char *str = new char[size]; 

그들은 유일한 방법은 얻을 정확히 맞는 크기는 당신이 읽을려고 얼마나 많은 문자를 아는 것입니다. 파일을 읽는 중이라면 가장 가까운 개행 (또는 다른 조건)을 찾고 그 배열이 얼마나 큰지 정확히 알 수 있습니다. 예 :

int numChars = computeNeededSpace(someFileHandle); 
char *readBuffer = new char[numChars]; 
fread(someFileHandle, readBuffer, numChars); //probly wrong parameter order 

다른 방법은 없습니다. 프로그램의 관점에서, 사용자가 몇 개의 키를 누를지를 어떻게 알 수 있습니까? 가장 좋은 방법은 사용자 또는 입력을 제한하는 것입니다.

버퍼의 연결된 목록을 만들고 버퍼 덩어리를 할당 한 다음 나중에 연결하는 것과 같은 몇 가지 더 복잡한 작업이 있습니다. 그러나 나는 그것이 당신이 여기에서 원했던 대답이 아니라고 생각합니다.

편집 : 대부분의 언어에는 이것을 숨기는 string/inputbuffer 클래스가 있습니다.

+1

'new'는 C가 아니라 C++입니다. –

+0

우, 예, 저는 항상 그렇게합니다 .... 새로운 것 대신에 malloc을 사용하십시오. (습관) –

1

읽을 때까지 문자열 길이를 결정할 방법이 없으므로 고정 길이 버퍼로 읽는 것이 유일한 선택입니다.

문자열을 작은 청크로 읽을 수있는 대안이 있다고 가정하지만, 한 번에 충분한 정보를 제공하지 않는 응용 프로그램에 따라 달라질 수 있습니다.

아마도이 딜레마를 처리하는 가장 쉬운 방법은 특정 문자열 입력 (#define-이 값에 대한 상수가 도움이 됨)에 대한 최대 길이를 정의하는 것입니다. 문자열을 읽을 때마다이 미리 결정된 크기의 버퍼를 사용하지만 최대 문자 수를 지정할 수 있도록 문자열 명령의 strncpy() 형식을 사용해야합니다. 일반적으로 사용되는 일부 유형의 문자열 (예 : 파일 이름 또는 경로)에는 시스템 정의 최대 길이가있을 수 있습니다.

올바르게 사용하는 한 고정 크기 배열을 선언 할 때 본질적으로 '잘못되었습니다.'(적절한 경계 검사를 수행하고 입력이 배열을 오버플로하는 경우를 처리). 사용되지 않는 메모리가 할당 될 수 있지만, 불행하게도 C 언어는 문자열과 관련하여 많은 작업을하지 않습니다.

6

데이터를 읽었을 때 버퍼의 크기는 고정되어 있으므로 불가피합니다.

그러나 할 수있는 일은 fgets를 사용하여 데이터를 읽은 다음 마지막 문자가 '\ n'(또는 파일 끝에 도달했는지)인지 확인하고 그렇지 않은 경우 realloc 버퍼를 확인하고, 그리고 더 많은 것을 읽으십시오.

필자는 거의 찾아 내지 못하지만 일반적으로 읽기 용으로 하나의 고정 버퍼를 할당하고 데이터를 읽은 다음 동적으로 복사본을위한 공간을 할당하고 실제로 차지하는만큼의 공간 만 할당합니다. 원래 사용했던 전체 크기의 버퍼.

2

고정 버퍼를 할당해야합니다. 크기가 작아지면 realloc()보다 크기가 커지고 계속됩니다.

0

고정 된 크기의 버퍼 트리를 만들 수있는 문자열 Ropes의 개념이 있습니다. 여전히 고정 크기의 버퍼를 가져야합니다. 실제로는 그렇게 할 필요가 없지만, 이것은 문자열을 동적으로 구축하는 꽤 깔끔한 방법입니다.

0

당신은 당신을위한 버퍼 관리 및 재 할당을 수행하는 척 매 사냥꾼의 공개 ggets 기능을 사용할 수 없습니다 : http://cbfalconer.home.att.net/download/index.htm

편집 : 척 매 사냥꾼의 웹 사이트는 더 이상 사용할 수 없습니다. archive.org still has a copyI'm hosting a copy too.

+0

링크가 작동하지 않습니다. – Paulpjmmchugh

+0

@Paulpjmmchugh Chuck Falconer가 세상을 떠난 것처럼 보입니다. 다른 사본에 대한 링크를 제공했습니다. – jamesdlin

관련 문제