我试图从用户获得一些数据,并将其发送到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并发送一个合适的字符串。
我试图从用户获得一些数据,并将其发送到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并发送一个合适的字符串。
当前回答
如果每一行都有'\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';
}
}
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';
因为你将使用单引号而不是双引号。如果你想了解更多,这里有一个关于单引号和双引号的链接
也许最简单的解决方案是使用我最喜欢的一个鲜为人知的函数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”。
我的新手方式;-)请让我知道这是正确的。这似乎对我所有的案子都有效:
#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;
}
以最明显的方式删除换行符的步骤:
通过使用strlen(), header string.h来确定NAME内部字符串的长度。注意,strlen()不计算结束的\0。
size_t sl = strlen(NAME);
查看字符串是否以一个\0字符(空字符串)开头或只包含一个\0字符。在这种情况下,sl将为0,因为如上所述strlen()不会计算\0,并在它第一次出现时停止:
if(sl == 0)
{
// Skip the newline replacement process.
}
检查正确字符串的最后一个字符是否是换行符'\n'。如果是这种情况,将\n替换为\0。注意,索引计数从0开始,所以我们需要执行NAME[sl - 1]:
if(NAME[sl - 1] == '\n')
{
NAME[sl - 1] = '\0';
}
请注意,如果您只在fgets()字符串请求时按下Enter(字符串内容仅由换行符组成),则NAME中的字符串此后将成为空字符串。
我们可以结合第二步。和3。通过使用逻辑运算符&&,将它们组合在一个if语句中:
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处停止,直到该空字符。
除了这个问题本身。尽量避免双重否定,这会使你的代码不清晰:(fgets(Name, sizeof Name, stdin) != NULL){}。你可以简单地执行if (fgets(Name, sizeof Name, stdin) == NULL){}。