sfa*_*tor 210 c string gcc newline fgets
我试图从用户那里获取一些数据并将其发送到gcc中的另一个函数.代码是这样的.
printf("Enter your Name: ");
if (!(fgets(Name, sizeof Name, stdin) != NULL)) {
fprintf(stderr, "Error reading Name.\n");
exit(1);
}
Run Code Online (Sandbox Code Playgroud)
但是,我发现它最后有一个换行符\n.所以,如果我输入John它最终发送John\n.如何删除它\n并发送正确的字符串.
Tim*_*Čas 390
也许最简单的解决方案使用我最喜欢的一个鲜为人知的功能strcspn():
buffer[strcspn(buffer, "\n")] = 0;
Run Code Online (Sandbox Code Playgroud)
如果你想要它也处理'\r'(比如,如果流是二进制):
buffer[strcspn(buffer, "\r\n")] = 0; // works for LF, CR, CRLF, LFCR, ...
Run Code Online (Sandbox Code Playgroud)
该函数计算字符数,直到它击中a '\r'或a '\n'(换句话说,它找到第一个'\r'或者'\n').如果没有碰到任何东西,它会停在'\0'(返回字符串的长度).
请注意,即使没有换行,这也可以正常工作,因为strcspn在a处停止'\0'.在这种情况下,整条生产线只是替换'\0'为'\0'.
Jer*_*fin 133
有点丑陋的方式:
char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
*pos = '\0';
else
/* input too long for buffer, flag error */
Run Code Online (Sandbox Code Playgroud)
有点奇怪的方式:
strtok(Name, "\n");
Run Code Online (Sandbox Code Playgroud)
请注意,strtok如果用户输入空字符串(即仅按Enter),则该功能无法按预期工作.它使\n角色完好无损.
当然还有其他一些.
Jam*_*ris 82
size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n')
name[ln] = '\0';
Run Code Online (Sandbox Code Playgroud)
chu*_*ica 16
以下是'\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] = '\0';
}
Run Code Online (Sandbox Code Playgroud)
现在使用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通过阅读fgets()是'\0'.输入以嵌入式开头时会发生这种情况'\0'.然后在合法范围之外肯定buffer[len -1]会buffer[SIZE_MAX]访问内存buffer.黑客可能在愚蠢地阅读UTF16文本文件时尝试或找到的东西.写这个答案时,这就是答案的状态.后来一个非OP编辑它包括像这个答案的检查代码"".
size_t len = strlen(buffer);
if (buffer[len - 1] == '\n') { // FAILS when len == 0
buffer[len -1] = '\0';
}
Run Code Online (Sandbox Code Playgroud)sprintf(buffer,"%s",buffer);是未定义的行为:参考.此外,它不会保存任何前导,分隔或尾随空格.现在已删除.
[编辑由于后来的好回答 ]与方法buffer[strcspn(buffer, "\n")] = 0;相比,除了性能之外,1衬垫没有问题strlen().鉴于代码正在进行I/O(CPU时间的黑洞),修剪性能通常不是问题.如果以下代码需要字符串的长度或具有高度的性能意识,请使用此strlen()方法.否则这strcspn()是一个很好的选择.
Ami*_*bha 10
如果每一行都有 '\n',直接从 fgets 输出中删除 '\n'
line[strlen(line) - 1] = '\0';
Run Code Online (Sandbox Code Playgroud)
除此以外:
void remove_newline_ch(char *line)
{
int new_line = strlen(line) -1;
if (line[new_line] == '\n')
line[new_line] = '\0';
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
299143 次 |
| 最近记录: |