사용자로부터 일부 데이터를 가져 와서 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
하고 적절한 문자열을 보내 려면 어떻게해야합니까?
답변
약간 못생긴 방법 :
char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
*pos = '\0';
else
/* input too long for buffer, flag error */
약간 이상한 방법 :
strtok(Name, "\n");
strtok
사용자가 빈 문자열을 입력하면 (예 : Enter 만 누름) 이 기능은 예상대로 작동하지 않습니다. \n
캐릭터를 그대로 둡니다 .
물론 다른 것도 있습니다.
답변
아마도 가장 간단한 해결책은 내가 좋아하는 거의 알려지지 않은 기능 중 하나를 사용하는 것입니다 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'
.
답변
size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n')
name[ln] = '\0';
답변
아래는에 '\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'
위치가 포함되지 않습니다 .
다른 답변의 문제 :
-
strtok(buffer, "\n");
(가) 제거에 실패'\n'
할 때buffer
입니다"\n"
. 이 답변에서 -이 제한 이후에 경고하기 위해이 답변 이후 수정되었습니다. -
첫 번째
char
by byfgets()
가 인 경우는 드물지만 다음에 실패합니다'\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'; }
-
sprintf(buffer,"%s",buffer);
정의되지 않은 동작입니다 : Ref . 또한 선행, 분리 또는 후행 공백을 저장하지 않습니다. 이제 삭제되었습니다 . -
[나중에 좋은 답변 으로 편집 ] 접근 방식
buffer[strcspn(buffer, "\n")] = 0;
과 비교할 때 성능 이외 의 1 라이너에는 문제가 없습니다strlen()
. 트리밍 성능은 일반적으로 코드가 I / O를 수행 할 때 문제가되지 않습니다. CPU 시간의 블랙홀입니다. 다음 코드는 문자열 길이가 필요하거나 성능을 높이려면이strlen()
방법을 사용하십시오 . 그렇지 않으면strcspn()
훌륭한 대안입니다.
답변
모든 줄에 ‘\ 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';
}
답변
단일 ‘\ 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';
}
}
답변
내 초보자 방법 😉 그것이 올바른지 알려주십시오. 내 모든 경우에 효과가있는 것 같습니다.
#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;
}