fgets () 입력에서 후행 줄 바꿈 문자 제거


235

사용자로부터 일부 데이터를 가져 와서 gcc의 다른 함수로 보내려고합니다. 코드는 이와 같습니다.

printf("Enter your Name: ");
if (!(fgets(Name, sizeof Name, stdin) != NULL)) {
    fprintf(stderr, "Error reading Name.\n");
    exit(1);
}

그러나 \n끝에 줄 바꿈 문자 가 있음을 알았습니다 . 그래서 입력 John하면 전송이 끝납니다 John\n. 그것을 제거 \n하고 적절한 문자열을 보내 려면 어떻게해야합니까?


21
if (!fgets(Name, sizeof Name, stdin))(최소한 두 가지 부정,! 및! =을 사용하지 마십시오)

4
@Roger Pate는 "두 가지 부정을 사용하지 마십시오"-> 흠, 우리가 깊이 "만두 지"및 "부정"을 파헤 치면 모두 부정 입니다. ;-). 아마도 "사용합니다 if (fgets(Name, sizeof Name, stdin)) {.
— chux-복원 자 Monica

3
@ chux, 난 당신이 의미 확신if (fgets(Name, sizeof Name, stdin) == NULL ) {
— R Sahu

@RSahu True : 성가신 !:
— chux-복원 모니카

답변:


154

약간 못생긴 방법 :

char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
    *pos = '\0';
else
    /* input too long for buffer, flag error */

약간 이상한 방법 :

strtok(Name, "\n");

strtok사용자가 빈 문자열을 입력하면 (예 : Enter 만 누름) 이 기능은 예상대로 작동하지 않습니다. \n캐릭터를 그대로 둡니다 .

물론 다른 것도 있습니다.


7
스레드를 인식하는 (즉, 다중 스레드 플랫폼을 대상으로하는 대부분의) C 런타임 라이브러리는 스레드 strtok()로부터 안전합니다 ( '인터 통화'상태에 스레드 로컬 스토리지를 사용함). 즉, 일반적으로 비표준 (그러나 일반적인) strtok_r()변형 을 사용하는 것이 좋습니다 .
— Michael Burr

2
귀하의 strtok접근 방식 과 유사한 완전히 스레드 안전하고 재진입 변형에 대한 내 답변을 참조하십시오 (빈 입력으로 작동 함). 실제로 구현하는 좋은 방법 strtok은 strcspnand 를 사용하는 것 strspn입니다.
— Tim Čas

2
너무 긴 라인의 위험이있는 환경에있는 경우 else 케이스를 처리하는 것이 중요합니다. 입력을 자동으로 자르면 매우 심각한 버그가 발생할 수 있습니다.
— Malcolm McLean

2
원 라이너를 좋아하고 glibc를 사용하는 경우을 사용해보십시오 *strchrnul(Name, '\n') = '\0';.
— twobit

때 strchr(Name, '\n') == NULL다음 옆에서 "입력 너무 오래 버퍼, 플래그 오류에 대해"다른 가능성이 존재, :의 마지막 문자 stdin로 끝날하지 않았 '\n'거나 드문 임베디드 널 (null) 문자는 읽을 수 있었다.
— chux-Reinstate Monica

439

아마도 가장 간단한 해결책은 내가 좋아하는 거의 알려지지 않은 기능 중 하나를 사용하는 것입니다 strcspn().

buffer[strcspn(buffer, "\n")] = 0;

'\r'스트림을 바이너리로 처리하는 경우에도 처리 하려면 :

buffer[strcspn(buffer, "\r\n")] = 0; // works for LF, CR, CRLF, LFCR, ...

그것은을 돌 때까지이 기능은 문자의 수를 계산 '\r'또는이 '\n'(즉, 그것은 처음 발견 '\r'또는 '\n'). 아무 것도 맞지 않으면 '\0'(문자열 길이를 반환) 에서 멈 춥니 다 .

이 때문에, 더 줄 바꿈이없는 경우에도 잘 작동합니다 strcspn멈추는에 '\0'. 그 경우에, 전체 행은 단순히 대체 '\0'하여 '\0'.


30
심지어 접근 방식에 대한 슬픔을 유발하는 buffer것으로 시작 하는 것보다 드문 경우를 처리합니다 . '\0'buffer[strlen(buffer) - 1] = '\0';
— chux-복원 모니카

5
@ chux : 응, 더 많은 사람들이 알고 있었으면 좋겠다 strcspn(). 라이브러리에서 더 유용한 기능 중 하나 인 IMO. 저는 오늘 이와 같은 일반적인 C 핵을 작성하고 게시하기로 결정했습니다. codepad.org/2lBkZk0w를strtok_r 사용 strcspn하고 구현 한 구현체 strspn: codepad.org/2lBkZk0w ( 경고 : 버그가 없다는 것을 보장 할 수는 없습니다; 서둘러 작성되었으며 아마도 몇 가지가있을 것입니다). 그래도 아직 게시 할 부분은 없지만 유명한 "비트 트위들 링 핵"의 정신으로 만들려고합니다.
— Tim Čas

4
견고하게 다듬는fgets() 방법을 조사했습니다 . 이것은 유일한 올바른 하나의 라이너 인 strcspn()것 같습니다 . 간단하지는 않지만 빠릅니다. strlen
— chux-복원 모니카

6
@sidbushes : 제목과 내용 모두에서 질문 은 fgets()입력 에서 후행 줄 바꿈에 대해 묻습니다 . 어느 것도 항상 첫 번째 줄 바꿈입니다.
— Tim Čas

9
@sidbushes : 어디에서 왔는지 이해하지만 특정 용어에 대한 Google 검색 결과에 대한 책임을지지 않습니다. 나와 Google이 아니라 대화하십시오.
— Tim Čas

83
size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n') 
    name[ln] = '\0';

8
문자열이 비어 있으면 예외가 발생합니까? 범위를 벗어난 인덱스처럼.
— Edward Olamisan

1
@EdwardOlamisan, 그러나 문자열은 결코 비어 있지 않습니다.
— 제임스 모리스

5
@James Morris 비정상적인 경우 fgets(buf, size, ....)-> strlen(buf) == 0. 1) fgets()첫 번째 chara 로 읽습니다 '\0'. 2) size == 13) fgets()반환 NULL하면 buf내용이 무엇이든 될 수 있습니다. (OP의 코드는 NULL을 테스트합니다) 제안 :size_t ln = strlen(name); if (ln > 0 && name[ln-1] == '\n') name[--ln] = '\0';
— chux-Monica Monica 복원

2
문자열이 비어 있으면 어떻게합니까? ln사실 size_t은 부호가 없으므로 임의의 메모리에 쓰는 경우 -1 이됩니다. 나는 당신이 사용 ssize_t하고 싶다고 생각하고 ln> 0입니다.
— abligh

2
@ legends2k : 컴파일 타임 값에 대한 검색 (특히에서와 같이 0 값 strlen)은 일반 char-by-char 검색보다 훨씬 효율적으로 구현 될 수 있습니다. 어떤 이유로 나는 것보다이 솔루션 더 나은 생각 하는데요 strchr또는 strcspn기초 것.
— AnT

17

아래는에 '\n'의해 저장된 문자열에서 잠재력을 제거하는 빠른 방법 fgets()입니다. 두 가지 테스트로을
사용 strlen()합니다.

char buffer[100];
if (fgets(buffer, sizeof buffer, stdin) != NULL) {

  size_t len = strlen(buffer);
  if (len > 0 && buffer[len-1] == '\n') {
    buffer[--len] = '\0';
  }

지금 사용 buffer하고 len필요에.

이 방법은 len후속 코드 에 대한 값 의 부작용이 있습니다. 보다 빠를 수 있습니다 strchr(Name, '\n'). YMMV를 참조 하지만 두 방법 모두 작동합니다.


buffer원래부터 fgets()에 포함되지 않습니다 "\n": 어떤 상황에서
A) 라인이 너무 오랫동안이었다 buffer때문에 만 char가 이전 '\n'에 저장됩니다 buffer. 읽지 않은 문자는 스트림에 남아 있습니다.
B) 파일의 마지막 줄은로 끝나지 않았습니다 '\n'.

입력에 널 문자가 포함되어 있으면 '\0'보고 된 길이 strlen()에 '\n'위치가 포함되지 않습니다 .


다른 답변의 문제 :

  1. strtok(buffer, "\n");(가) 제거에 실패 '\n'할 때 buffer입니다 "\n". 이 답변에서 -이 제한 이후에 경고하기 위해이 답변 이후 수정되었습니다.

  2. 첫 번째 charby by fgets()가 인 경우는 드물지만 다음에 실패합니다 '\0'. 입력이 포함 된로 시작될 때 발생합니다 '\0'. 이어서 buffer[len -1]된다 buffer[SIZE_MAX]의 정상적인 범위 밖에 확실히 액세스 메모리 buffer. 해커가 UTF16 텍스트 파일을 어리석게 읽을 때 시도하거나 발견 할 수있는 것. 이 답변이 작성되었을 때 의 답변 상태입니다 . 나중에 비 OP 가이 답변의 check과 같은 코드를 포함하도록 편집했습니다 "".

    size_t len = strlen(buffer);
    if (buffer[len - 1] == '\n') {  // FAILS when len == 0
      buffer[len -1] = '\0';
    }
    
  3. sprintf(buffer,"%s",buffer);정의되지 않은 동작입니다 : Ref . 또한 선행, 분리 또는 후행 공백을 저장하지 않습니다. 이제 삭제되었습니다 .

  4. [나중에 좋은 답변 으로 편집 ] 접근 방식 buffer[strcspn(buffer, "\n")] = 0;과 비교할 때 성능 이외 의 1 라이너에는 문제가 없습니다 strlen(). 트리밍 성능은 일반적으로 코드가 I / O를 수행 할 때 문제가되지 않습니다. CPU 시간의 블랙홀입니다. 다음 코드는 문자열 길이가 필요하거나 성능을 높이려면이 strlen()방법을 사용하십시오 . 그렇지 않으면 strcspn()훌륭한 대안입니다.


유용한 답변에 감사드립니다. ?를 strlen(buffer)사용하여 버퍼 크기를 동적으로 할당 할 때 사용할 수 있습니까 malloc?
— rrz0

@ Rrz0 buffer = malloc(allocation_size); length = strlen(buffer);이 잘못되었습니다. 메모리가 가리키는 데이터를 buffer알 수 없습니다. buffer = malloc(allocation_size_4_or_more); strcpy(buffer, "abc"); length = strlen(buffer);괜찮아
— chux-복원 모니카

감사합니다 !! 저는 CS 과정을 수강하며 과제 중 하나에 큰 도움이되었습니다. 나는 소스 코드에서 당신의 대답을 인정했습니다.
— Nathaniel Hoyt

8

모든 줄에 '\ n'이 있으면 fgets 출력에서 ​​'\ n'을 제거하도록 지시하십시오.

line[strlen(line) - 1] = '\0';

그렇지 않으면:

void remove_newline_ch(char *line)
{
    int new_line = strlen(line) -1;
    if (line[new_line] == '\n')
        line[new_line] = '\0';
}

1
대신 사용 하는 것이 더 안전 합니다 . strnlenstrlen
— Mike Mertsock 2016 년

3
링크 된 질문의 첫 번째 답변에 대한 주석은 "strlen (), strcmp () 및 strdup ()은 안전합니다. 'n'대안은 추가 기능을 제공합니다."
— Étienne

4
@esker 아니오, 그렇지 않습니다. 를 삽입 n해도 안전이 마술처럼 향상되지는 않습니다.이 경우 실제로 코드가 더 위험 해집니다. 마찬가지로 strncpy매우 안전하지 않은 기능입니다. 연결 한 게시물이 좋지 않습니다.
— MM

3
빈 문자열 ( "")에 대해 비참하게 실패합니다 . 또한 not을 strlen()반환합니다 . size_tint
— alk

4
이것은 빈 문자열에 대해 안전하지 않으며 인덱스 -1에 씁니다. 이것을 사용하지 마십시오.
— Jean-François Fabre

3

단일 '\ n'트리밍의 경우

void remove_new_line(char* string)
{
    size_t length = strlen(string);
    if((length > 0) && (string[length-1] == '\n'))
    {
        string[length-1] ='\0';
    }
}

여러 개의 '\ n'트리밍의 경우

void remove_multi_new_line(char* string)
{
  size_t length = strlen(string);
  while((length>0) && (string[length-1] == '\n'))
  {
      --length;
      string[length] ='\0';
  }
}

1
?를 if사용하여 단순히 하나의 조건을 작성할 수 있는데 왜 중첩 &&합니까? 그 while루프는 이상한 구조를 가지고 있습니다. 단순히 될 수 있습니다 while (length > 0 && string[length-1] == '\n') { --length; string[length] = '\0'; }.
— melpomene

@melpomene 제안에 감사드립니다. 코드를 업데이트하십시오.
— BEPP

1
첫 번째 함수가 더 자연스럽게 다음과 같이 정의되어 있다고 제안합니다 size_t length = strlen(string); if (length > 0 && string[length-1] == '\n') { string[length-1] = '\0'; }. 또한 두 번째 정의를 더 잘 반영합니다 ( if대신에 사용 while).
— melpomene

@elpomene 감사합니다. 말이 되는군요. 코드를 업데이트했습니다.
— BEPP

1

내 초보자 방법 ;-) 그것이 올바른지 알려주십시오. 내 모든 경우에 효과가있는 것 같습니다.

#define IPT_SIZE 5

int findNULL(char* arr)
{
    for (int i = 0; i < strlen(arr); i++)
    {
        if (*(arr+i) == '\n')
        {
            return i;
        }
    }
    return 0;
}

int main()
{
    char *input = malloc(IPT_SIZE + 1 * sizeof(char)), buff;
    int counter = 0;

    //prompt user for the input:
    printf("input string no longer than %i characters: ", IPT_SIZE);
    do
    {
        fgets(input, 1000, stdin);
        *(input + findNULL(input)) = '\0';
        if (strlen(input) > IPT_SIZE)
        {
            printf("error! the given string is too large. try again...\n");
            counter++;
        }
        //if the counter exceeds 3, exit the program (custom function):
        errorMsgExit(counter, 3); 
    }
    while (strlen(input) > IPT_SIZE);

//rest of the program follows

free(input)
return 0;
}

1

가장 분명한 방법으로 개행 문자를 제거하는 단계 :

  1. , header NAME를 사용하여 문자열의 길이를 결정하십시오 . 참고 종료를 계산하지 않습니다 .strlen()string.hstrlen()\0
size_t sl = strlen(NAME);

  1. 문자열이 하나의 \0문자로 시작하거나 하나의 문자 만 포함하는지 확인하십시오 (빈 문자열). 이때 sl것 0때문에 strlen()I가 계산 나던 위에 상기와 같은 \0그것의 첫번째 발생 정차 :
if(sl == 0)
{
   // Skip the newline replacement process.
}

  1. 적절한 문자열의 마지막 문자가 개행 문자인지 확인하십시오 '\n'. 이 경우, 대체 \n로모그래퍼 \0. 인덱스 수는 처음부터 시작 0되므로 다음을 수행해야합니다 NAME[sl - 1].
if(NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

fgets()문자열 요청 에서 Enter 만 누른 경우 (문자열 내용은 개행 문자로만 구성됨) NAME이후 문자열은 빈 문자열이됩니다.


  1. if논리 연산자를 사용하여 2 단계와 3 단계를 하나의 문장으로 결합 할 수 있습니다 &&.
if(sl > 0 && NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

  1. 완성 된 코드 :
size_t sl = strlen(NAME);
if(sl > 0 && NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

fgets매번 다시 입력하지 않고 일반적으로 출력 문자열 을 처리하여이 기술을 사용하는 함수를 선호하는 경우 다음과 fgets_newline_kill같습니다.

void fgets_newline_kill(char a[])
{
    size_t sl = strlen(a);

    if(sl > 0 && a[sl - 1] == '\n')
    {
       a[sl - 1] = '\0';
    }
}

제공된 예에서 다음과 같습니다.

printf("Enter your Name: ");

if (fgets(Name, sizeof Name, stdin) == NULL) {
    fprintf(stderr, "Error reading Name.\n");
    exit(1);
}
else {
    fgets_newline_kill(NAME);
}

입력 문자열에 \0s 가 포함되어 있으면이 방법이 작동하지 않습니다 . 이 경우 strlen()첫 번째까지만 문자 수를 반환합니다 \0. 그러나 대부분의 문자열 읽기 기능은 일반적으로 처음에 멈추고 \0해당 null 문자까지 문자열을 가져 오기 때문에 이것은 일반적인 접근 방식이 아닙니다.

그 자체로 질문을 제외하고. 코드가 명확하지 않은 이중 부정을 피하십시오 if (!(fgets(Name, sizeof Name, stdin) != NULL) {}. 간단하게 할 수 있습니다 if (fgets(Name, sizeof Name, stdin) == NULL) {}.


왜 당신이 이것을하고 싶은지 모르겠습니다. 줄 바꿈을 제거하는 요점은 문자열을 null로 종료하는 것이 아닙니다. 개행을 제거하는 것입니다. 교체 \nA를을 \0상기 끝 문자열은 줄 바꿈을 "제거"하는 방법입니다. 그러나 \n문자열 내 문자를 바꾸면 기본적으로 문자열이 변경됩니다. 의도적으로 여러 줄 바꿈 문자가있는 문자열을 갖는 것은 드문 일이 아니며, 이는 해당 문자열의 끝을 효과적으로 잘라냅니다. 이러한 줄 바꿈 을 제거 하려면 배열 내용을 왼쪽으로 이동하여를 덮어 씁니다 \n.
— 전 nihilo

@exnihilo 누군가 어떻게 사용하여 여러 줄 바꿈이있는 문자열을 입력 할 수 fgets()있습니까?
— RobertS는

글을 여러 번 호출하여 얻은 문자열을 연결할 수 있습니다 fgets(). 그러나 나는 당신의 반대 의견을 이해하지 못합니다 : 당신은 여러 줄 바꿈을 처리하는 코드를 제안하는 사람입니다.
— 전 nihilo

@exnihilo 당신이 옳습니다, 나는 전략을 너무 생각할 것입니다. 원하는 결과를 얻을 수있는 매우 가혹하지만 가능한 방법을 추가하고 싶었습니다.
— RobertS는

@exnihilo 내 대답을 완전히 편집하고 strlen등 을 사용하여 주요 접근 방식을 따랐습니다 . 중복되지 않는 이유 : 1. 단계별 코드 설명. 2. 기능 및 컨텍스트 기반 솔루션으로 제공됩니다. 이중 부정 표현을 피하기 위해 힌트.
— RobertS는

0

Tim Čas one liner는 fgets 호출로 얻은 문자열에 놀랍습니다. 마지막에 줄 바꿈이 하나 포함되어 있기 때문입니다.

다른 컨텍스트에 있고 둘 이상의 개행을 포함 할 수있는 문자열을 처리하려는 경우 strrspn을 찾고있을 수 있습니다. POSIX가 아니므로 모든 Unices에서 찾을 수 없습니다. 나는 내 자신의 필요를 위해 하나를 썼습니다.

/* Returns the length of the segment leading to the last 
   characters of s in accept. */
size_t strrspn (const char *s, const char *accept)
{
  const char *ch;
  size_t len = strlen(s);

more: 
  if (len > 0) {
    for (ch = accept ; *ch != 0 ; ch++) {
      if (s[len - 1] == *ch) {
        len--;
        goto more;
      }
    }
  }
  return len;
}

C에서 Perl chomp에 해당하는 것을 찾는 사람들에게는 이것이 있다고 생각합니다 (chomp는 후행 줄 바꿈 만 제거합니다).

line[strrspn(string, "\r\n")] = 0;

strrcspn 함수 :

/* Returns the length of the segment leading to the last 
   character of reject in s. */
size_t strrcspn (const char *s, const char *reject)
{
  const char *ch;
  size_t len = strlen(s);
  size_t origlen = len;

  while (len > 0) {
    for (ch = reject ; *ch != 0 ; ch++) {
      if (s[len - 1] == *ch) {
        return len;
      }
    }
    len--;
  }
  return origlen;
}

1
"마지막에 줄 바꿈이 하나 있다는 것을 알고 있기 때문에." -> '\n'없거나 문자열이 인 경우 에도 작동합니다 "".
— chux-복원 Monica Monica

첫 번째 코멘트 chux에 대한 응답으로, 내 대답은 그것을 유지합니다. 내가 strrcspn없을 때 나는 resetlen을 던져야했다 \n.
— Philippe A.

왜 goto end;대신에 사용 return len;합니까?
— chqrlie

@chqrlie 나는이 우아한 2 레벨 루프에서 벗어나야했습니다. 해가됐다. 왜 안가?
— Philippe A.

goto코드 에는 두 가지 종류가 있습니다 : 문장 goto으로 대체 될 수 없는 쓸모없는 것과 악으로 간주 return되는 뒤로 goto. 사용하여 strchr구현하는 데 도움 strrspn과 strrcspn: 간단한 방식으로 size_t strrspn(const char *s, const char *accept) { size_t len = strlen(s); while (len > 0 && strchr(accept, s[len - 1])) { len--; } return len; }와size_t strrcspn(const char *s, const char *reject) { size_t len = strlen(s); while (len > 0 && !strchr(reject, s[len - 1])) { len--; } return len; }
— chqrlie

0

using getline이 보안 문제를 무시하지 않고 포인터를 괄호로 묶는 옵션 인 경우 getline문자 수를 반환하므로 문자열 함수를 피할 수 있습니다 . 아래와 같은 것

#include<stdio.h>
#include<stdlib.h>
int main(){
char *fname,*lname;
size_t size=32,nchar; // Max size of strings and number of characters read
fname=malloc(size*sizeof *fname);
lname=malloc(size*sizeof *lname);
if(NULL == fname || NULL == lname){
 printf("Error in memory allocation.");
 exit(1);
}
printf("Enter first name ");
nchar=getline(&fname,&size,stdin);
if(nchar == -1){ // getline return -1 on failure to read a line.
 printf("Line couldn't be read.."); 
 // This if block could be repeated for next getline too
 exit(1);
}
printf("Number of characters read :%zu\n",nchar);
fname[nchar-1]='\0';
printf("Enter last name ");
nchar=getline(&lname,&size,stdin);
printf("Number of characters read :%zu\n",nchar);
lname[nchar-1]='\0';
printf("Name entered %s %s\n",fname,lname);
return 0;
}

참고 : [ 보안 문제 ] 는 getline무시해서는 안됩니다.


-1

아래 함수는 Github에서 유지 관리하는 문자열 처리 라이브러리의 일부입니다. 정확하게 원하는 문자열을 제거하고 원하지 않는 문자를 제거합니다.

int zstring_search_chr(const char *token,char s){
    if (!token || s=='\0')
        return 0;

    for (;*token; token++)
        if (*token == s)
            return 1;

    return 0;
}

char *zstring_remove_chr(char *str,const char *bad) {
    char *src = str , *dst = str;
    while(*src)
        if(zstring_search_chr(bad,*src))
            src++;
        else
            *dst++ = *src++;  /* assign first, then incement */

    *dst='\0';
        return str;
}

사용 예는 다음과 같습니다.

Example Usage
      char s[]="this is a trial string to test the function.";
      char const *d=" .";
      printf("%s\n",zstring_remove_chr(s,d));

  Example Output
      thisisatrialstringtotestthefunction

사용 가능한 다른 기능을 확인하거나 프로젝트에 기여할 수도 있습니다 :) https://github.com/fnoyanisi/zString


당신은 제거해야합니다 *에 *src++;와 확인 bad, token및 d const char *. 또한 왜 strchr대신에 사용 하지 zChrSearch않습니까? 당신의 기능에 *src있을 수 없습니다 . '\0'zStrrmv
— chqrlie

감사합니다 @chqrlie! 귀하의 제안을 반영하기 위해 코드를 업데이트했습니다 ..... zstring은 표준 라이브러리 기능을 사용하지 않고 문자열 조작 라이브러리를 만들기위한 재미있는 프로젝트로 시작되었으므로 사용하지 않았습니다.strchr
— fnisi

1
" 표준 라이브러리 함수를 사용하지 않고 문자열 조작 라이브러리 "를 작성하는 것은 좋은 연습이지만 다른 사람들에게 사용하도록 지시하는 이유는 무엇입니까? 무엇이든 표준 라이브러리보다 속도가 느리고 테스트가 적습니다.
— melpomene

이것은 질문에서 요구하는 것과 다른 일을하고 있습니다. 아마도 유일한 줄 바꿈을 제거하는 데 사용될 수 있지만 과도하게 느껴집니다.
— Jonathan Leffler

-1
 for(int i = 0; i < strlen(Name); i++ )
{
    if(Name[i] == '\n') Name[i] = '\0';
}

당신은 그것을 시도해야합니다. 이 코드는 기본적으로 '\ n'을 찾을 때까지 문자열을 반복합니다. 발견되면 '\ n'은 널 문자 종결 자 '\ 0'으로 대체됩니다.

이 줄에서 문자열이 아닌 문자를 비교하는 경우 strcmp ()를 사용할 필요가 없습니다.

if(Name[i] == '\n') Name[i] = '\0';

큰 따옴표가 아닌 작은 따옴표를 사용하기 때문입니다. 여기 당신이 더 많은 것을 알고 싶은 경우에 큰 따옴표 대 싱글에 대한 링크


2
코드 형식을 설명하고 편집하면 더 좋습니다.
— Anh Pham

일반적으로 익명 코드 행을 게시하는 대신 솔루션을 설명하는 것이 좋습니다. 좋은 답변을 작성하는 방법 과 전체 코드 기반 답변 설명을 읽을 수 있습니다 .
— Massimiliano Kraus

1
이것이 내가 처음으로 기여한 것이 유감입니다. 내가 고칠 게 피드백 주셔서 감사합니다
— Matheus Martins Jerônimo

3
비효율적이 : for(int i = 0; i < strlen(Name); i++ )호출 strlen(Name)여러 번 (루프 변경 Name[], 길이 정도) N, 이것은이다 O(N*N)솔루션. strlen(Name)O (N)`솔루션을 제공하는 데 필요한 경우 한 번만 호출하면 됩니다. 왜 int i대신에 사용 되는지 확실하지 않습니다 size_t i. 고려for(size_t i = 0; i < Name[i]; i++ )
— chux-Reinstate Monica

@chux 더 좋아요for (size_t i = 0; Name[i]; i++) { if (Name[i] == '\n') { Name[i] = '\0'; break; } }
— melpomene

-1

이거 한번 해봐:

        int remove_cr_lf(char *str)
        {
          int len =0;


          len = strlen(str);

          for(int i=0;i<5;i++)
          {
            if (len>0)
            if (str[len-1] == '\n')
            {
              str[len-1] = 0;
              len--;
            }

            if (len>0)
            if (str[len-1] == '\r')
            {
              str[len-1] = 0;
              len--;
            }
          }

          return 0;
        }

1
len = strlen(str)오버 플로우 수 strlen반환 size_t하지 int. 이상한 if (len>0) if (...)조건 은 무엇입니까 ? 당신은 몰라 &&? CR / LF의 여러 후행 인스턴스를 제거하려는 경우 왜 5로 제한합니까? 왜 모두 제거하지 않습니까? 함수가 int항상 리턴 할 때 리턴 유형을 갖는 이유는 무엇 0입니까? 왜 돌아 오지 void않습니까?
— melpomene
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.