fgets() 입력에서 말미의 줄바꿈 문자를 제거하는 중
사용자로부터 데이터를 받아 gcc의 다른 함수로 보내려고 합니다.암호는 이런 거예요.
printf("Enter your Name: ");
if (!(fgets(Name, sizeof Name, stdin) != NULL)) {
fprintf(stderr, "Error reading Name.\n");
exit(1);
}
행이 을 알 수 있습니다.\n
지막마 so래 so 라고 입력하면John
보내게 된다.John\n
그 '어디서'를 제거할 수 있을까요\n
적절한 스트링을 보냅니다.
아마도 가장 간단한 솔루션은 내가 가장 좋아하는 거의 알려지지 않은 함수 중 하나를 사용합니다.
buffer[strcspn(buffer, "\n")] = 0;
도 '\r'
( 림림이 ( ( ( ( ( ) : )
buffer[strcspn(buffer, "\r\n")] = 0; // works for LF, CR, CRLF, LFCR, ...
.'\r'
★★★'\n'
첫즉, 첫 번째를 찾습니다.'\r'
★★★★★★★★★★★★★★★★★」'\n'
안 ). 、 운 、 운 、 운 、 운 、 at at 、 the the the 。'\0'
(어느 쪽인가 하면)
은, 새로운이 없어도 정상적으로 합니다.이것은, 「」, 「」, 「」가 있기 때문입니다.strcspn
에 '\0'
줄 줄바꿈을 하고 '\0'
'\0'
.
우아한 방법:
Name[strcspn(Name, "\n")] = 0;
약간 못생긴 방법:
char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
*pos = '\0';
else
/* input too long for buffer, flag error */
조금 이상한 방법:
strtok(Name, "\n");
에 주의:strtok
사용자가 빈 문자열을 입력하면(즉, Enter만 누르면) 기능이 예상대로 작동하지 않습니다.이남.\n
자자그그 그다다다다다
물론 다른 사람들도 있다.
size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n')
name[ln] = '\0';
인 제거 합니다.'\n'
에 의해 fgets()
.
it it를 한다.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
그그 so sochar
'\n'
됩니다.buffer
읽지 않은 문자는 스트림에 남아 있습니다.
이 B)로 .'\n'
가 포함되어 있는 null 문자가 포함되어 있습니다.'\0'
되는 strlen()
에는 will will will will will the the는 포함되지 .'\n'
★★★★★★ 。
기타 답변:
strtok(buffer, "\n");
에'\n'
때buffer
"\n"
. 이 답변부터 - 이 답변 이후에 이 제한을 경고하기 위해 수정.은 첫 입니다.
char
읽다로 읽다fgets()
'\0'
된 입력으로 시작할 때'\0'
.그리고나서buffer[len -1]
becomes가 되다buffer[SIZE_MAX]
할 수 있는 것은, 확실히 「메모리」입니다.buffer
해커가 UTF16 텍스트파일을 우습게 읽을 때 시도하거나 발견할 수 있는 것.이 답변이 작성되었을 때의 답변 상태였습니다.나중에 비OP가 이 답변의 체크와 같은 코드를 포함하도록 편집했습니다.""
.size_t len = strlen(buffer); if (buffer[len - 1] == '\n') { // FAILS when len == 0 buffer[len -1] = '\0'; }
sprintf(buffer,"%s",buffer);
정의되지 않은 동작: 참조.또한 선행, 분리 또는 후행 공백을 저장하지 않습니다.삭제되었습니다.[나중에 좋은 답변으로 편집]라이너 1개는 문제없고
buffer[strcspn(buffer, "\n")] = 0;
.strlen()
perform. 에서는 I가 이루어지고 있기 는 보통 가 되지 은 CPU 의 블랙홀입니다.코드 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';
}
일반적으로 원하지 않는 데이터를 잘라내는 대신 처음부터 데이터를 쓰는 것을 피하십시오.버퍼에 새 줄을 넣지 않으려면 fget을 사용하지 마십시오.''를 합니다.getc
★★★★★★★★★★★★★★★★★」fgetc
★★★★★★★★★★★★★★★★★」scanf
과 같다 을 사용하다
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char Name[256];
char fmt[32];
if( snprintf(fmt, sizeof fmt, "%%%zd[^\n]", sizeof Name - 1) >= (int)sizeof fmt ){
fprintf(stderr, "Unable to write format\n");
return EXIT_FAILURE;
}
if( scanf(fmt, Name) == 1 ) {
printf("Name = %s\n", Name);
}
return 0;
}
에서는, 행은 읽지 , 「Newline」이라고 하는 도 모릅니다."%255[^\n]%*c"
sprintf(fmt, "%%%zd[^\n]%%*c", sizeof Name - 1);
a , scanf, scanf, scanf, scanf를 붙입니다.getchar()
.
가장 알기 쉬운 방법으로 줄 바꿈 문자를 삭제하는 절차는 다음과 같습니다.
- 에 있는 를 정하세요.
NAME
를 사용하여strlen()
, 「」string.h
해 주세요.strlen()
의 끝은 되지 않습니다.\0
.
size_t sl = strlen(NAME);
- 이 1로 하는지, 1로 합니다.
\0
문자(빈 문자열). 경우, 「 」sl
0
strlen()
상술한 바와 같이, 는 계산에 넣지 않는다.\0
.
if(sl == 0)
{
// Skip the newline replacement process.
}
- 합니다.
'\n'
「 」 「 」 「 」 「 」를 합니다.\n
a\0
카운트는 .에서합니다.0
때문에 해야 될 것 같아요.NAME[sl - 1]
:
if(NAME[sl - 1] == '\n')
{
NAME[sl - 1] = '\0';
}
것은 키뿐입니다.fgets()
request됨) 스트링 요구(스트링 요구)의NAME
그 후에는 빈 문자열이 됩니다.
- 수 요.
if
- operator - "논리 연산자 사용"&&
:
if(sl > 0 && NAME[sl - 1] == '\n')
{
NAME[sl - 1] = '\0';
}
- 완료된 코드:
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);
}
에 내장되어 있는 는, 이은 기능하지 않는 해 주세요.\0
그 안에 있어요.strlen()
에서는 첫 번째 까지는 됩니다.\0
은 보통 첫 문자열 읽기 때문에 접근법이 \0
그 늘 문자까지 문자열을 사용합니다.
문제는 제쳐두고..if (!(fgets(Name, sizeof Name, stdin) != NULL) {}
할 수 있어요.if (fgets(Name, sizeof Name, stdin) == NULL) {}
.
단일 '\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';
}
}
My Newbie way ;-) 맞다면 알려주세요.모든 케이스에서 효과가 있는 것 같습니다.
#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;
}
fgets 호출로 얻을 수 있는 문자열에는 Tim Chas 1개의 라이너가 매우 적합합니다.이것은, 마지막에 1개의 새로운 행이 포함되어 있기 때문입니다.
다른 컨텍스트에서 여러 줄의 새 행을 포함할 수 있는 문자열을 처리하는 경우 strrspn을 찾을 수 있습니다.이것은 POSIX가 아닙니다.즉, 모든 Unice에서 찾을 수 있는 것은 아닙니다.나는 내 필요에 따라 한 권을 썼다.
/* 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;
}
아래 함수는 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
for(int i = 0; i < strlen(Name); i++ )
{
if(Name[i] == '\n') Name[i] = '\0';
}
한번 시도해 보세요.이 코드는 기본적으로 '\n'을 찾을 때까지 문자열을 루프합니다.발견 시 '\n'은 null 문자 터미네이터 '\0'으로 대체됩니다.
이 행의 문자열이 아닌 문자를 비교하고 있으므로 strcmp()를 사용할 필요가 없습니다.
if(Name[i] == '\n') Name[i] = '\0';
큰따옴표가 아닌 작은따옴표를 사용할 것이기 때문입니다.자세한 내용은 싱글 따옴표와 더블 따옴표에 대한 링크를 참조하십시오.
「 」를 하고 있는 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
소홀히 해서는 안 됩니다.
이게 제 해결책입니다.아주 간단합니다.
// Delete new line
// char preDelete[256] include "\n" as newline after fgets
char deletedWords[256];
int iLeng = strlen(preDelete);
int iFinal = 0;
for (int i = 0; i < iLeng; i++) {
if (preDelete[i] == '\n') {
}
else {
deletedWords[iFinal] = preDelete[i];
iFinal++;
}
if (i == iLeng -1 ) {
deletedWords[iFinal] = '\0';
}
}
언급URL : https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input
'IT이야기' 카테고리의 다른 글
Vue.js - 도우미 기능을 단일 파일 컴포넌트로 글로벌하게 이용 가능 (0) | 2022.05.31 |
---|---|
C에서 부울 데이터형을 사용하는 방법 (0) | 2022.05.31 |
기존 HTML의 데이터를 사용하여 Vue 뷰 모델 로드 (0) | 2022.05.31 |
불변 컬렉션과 수정할 수 없는 컬렉션 (0) | 2022.05.31 |
Vuej 및 Vuex가 업데이트된 어레이를 렌더링하지 않음 (0) | 2022.05.31 |