Удаление завершающего символа новой строки из ввода fgets()
Я пытаюсь получить некоторые данные от пользователя и отправить его в другую функцию в gcc. Код что-то вроде этого.
printf("Enter your Name: ");
if (!(fgets(Name, sizeof Name, stdin) != NULL)) {
fprintf(stderr, "Error reading Name.n");
exit(1);
}
однако, я считаю, что он имеет строку n символ в конце. Так что если я войду John это заканчивается отправкой Johnn. Как мне удалить это n и отправить соответствующую строку.
12 ответов:
немного уродливый способ:
char *pos; if ((pos=strchr(Name, '\n')) != NULL) *pos = ''; else /* input too long for buffer, flag error */немного странный способ:
strtok(Name, "\n");отметим, что
strtokфункция не работает должным образом, если пользователь вводит пустую строку (т. е. давит только ввод). Он оставляет\nхарактер нетронутыми.есть и другие, конечно.
возможно, самое простое решение использует одну из моих любимых малоизвестных функций,
strcspn():buffer[strcspn(buffer, "\n")] = 0;если вы хотите, чтобы он также ручка
'\r'(скажем, если поток двоичных):buffer[strcspn(buffer, "\r\n")] = 0; // works for LF, CR, CRLF, LFCR, ...функция подсчитывает количество символов, пока не достигнет
'\r'или'\n'(другими словами, он находит первого'\r'или'\n'). Если он ничего не попадает, он останавливается на''(возврат длине строка.)обратите внимание, что это прекрасно работает, даже если нет новой строки, потому что
strcspnостанавливается на''. В этом случае можно просто заменить''С''.
Ниже приведен быстрый подход для удаления потенциала
'\n'из строки спасfgets().
Он используетstrlen()С 2 тестами.char buffer[100]; if (fgets(buffer, sizeof buffer, stdin) != NULL) { size_t len = strlen(buffer); if (len > 0 && buffer[len-1] == '\n') { buffer[--len] = ''; }теперь использовать
bufferиlenпо мере необходимости.этот метод имеет побочное преимущество
lenзначение для последующего кода. Это может быть легко быстрее, чемstrchr(Name, '\n'). Ref YMMV, но оба метода работают.
buffer, от оригиналаfgets()не будет содержать в"\n"под некоторые обстоятельства:
А) линия была слишком длинной дляbufferтолькоcharпредшествующий'\n'сохранен вbuffer. Непрочитанные символы остаются в потоке.
Б) последняя строка в файле не заканчивается на'\n'.если вход имеет встроенные нулевые символы
''в нем где-то, длина сообщилиstrlen()не будет'\n'расположение.
некоторые другие вопросы ответов:
strtok(buffer, "\n");не удается удалить'\n', когдаbufferи"\n". От этого ответ - внесены изменения после этого ответа, чтобы предупредить об этом ограничении.следующее терпит неудачу в редких случаях, когда первый
charчитатьfgets()- это''. Это происходит, когда ввод начинается со встроенного''. Тогдаbuffer[len -1]становитсяbuffer[SIZE_MAX]доступ к памяти, безусловно, вне законного диапазонаbuffer. Что-то хакер может попробовать или найти в глупо читать текстовые файлы UTF16. Это было состояние ответ когда этот ответ был написан. Позже non-OP отредактировал его, чтобы включить код, подобный проверке этого ответа на"".size_t len = strlen(buffer); if (buffer[len - 1] == '\n') { // FAILS when len == 0 buffer[len -1] = ''; }
sprintf(buffer,"%s",buffer);неопределено поведение: Ref. Кроме того, он не сохраняет никаких ведущих, разделительных или конечных пробелов. Сейчас удалены.[редактирование из-за хорошо позже ответ] нет никаких проблем с 1 вкладышем
buffer[strcspn(buffer, "\n")] = 0;кроме производительности по сравнению сstrlen()подход. Производительность в обрезке обычно не является проблемой, учитывая, что код делает ввод/вывод - черная дыра процессорного времени. Если следующий код нуждается в длине строки или имеет высокую производительность, используйте этоstrlen()подход. Иначе тоstrcspn()это прекрасная альтернатива.
прямой, чтобы удалить '\n 'из вывода fgets, если каждая строка имеет '\n'
line[strlen(line) - 1] = '';в противном случае:
void remove_newline_ch(char *line) { int new_line = strlen(line) -1; if (line[new_line] == '\n') line[new_line] = ''; }
для одиночного' \n ' trmming,
void remove_new_line(char* string) { size_t length = strlen(string); if((length > 0) && (string[length-1] == '\n')) { string[length-1] =''; } }для множественной' \n ' обрезки,
void remove_multi_new_line(char* string) { size_t length = strlen(string); while((length>0) && (string[length-1] == '\n')) { --length; string[length] =''; } }
Тим Čas один лайнер удивительно для строк, полученных при вызове fgets, потому что вы знаете, что они содержат одну новую строку в конце.
Если вы находитесь в другом контексте и хотите обрабатывать строки, которые могут содержать более одной новой строки, вы можете искать strrspn. Это не в POSIX, то есть вы не найдете его на всех Юниксов. Я написал один для моих собственных нужд.
/* 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; }для тех, кто ищет эквивалент Perl chomp в C, я думаю, что это он (только 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; }
for(int i = 0; i < strlen(Name); i++ ) { if(Name[i] == '\n') Name[i] = ''; }вы должны дать ему попробовать. Этот код в основном цикл через строку, пока он не найдет '\n'. Когда он будет найден '\n 'будет заменен на нулевой символ Терминатора '\0'
обратите внимание, что вы сравниваете символы, а не строки в этой строке, тогда нет необходимости использовать strcmp ():
if(Name[i] == '\n') Name[i] = '';поскольку вы будете использовать одинарные кавычки, а не двойные кавычки. здесь ссылка на одинарные и двойные кавычки, если вы хотите знать еще
при использовании
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]=''; printf("Enter last name "); nchar=getline(&lname,&size,stdin); printf("Number of characters read :%zu\n",nchar); lname[nchar-1]=''; printf("Name entered %s %s\n",fname,lname); return 0; }Примечание: The [ вопросы безопасности] С
getlineНе следует пренебрегать, хотя.
char name[1024]; unsigned int len; printf("Enter your name: "); fflush(stdout); if (fgets(name, sizeof(name), stdin) == NULL) { fprintf(stderr, "error reading name\n"); exit(1); } len = strlen(name); if (name[len - 1] == '\n') name[len - 1] = '';
функция ниже является частью библиотеки обработки строк, которую я поддерживаю на Github. Он удаляет и нежелательные символы из строки, именно то, что вы хотите
int zstring_search_chr(const char *token,char s){ if (!token || s=='') 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=''; 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
попробуй это:
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; }
Comments