我试图从用户获得一些数据,并将其发送到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并发送一个合适的字符串。
当前回答
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';
因为你将使用单引号而不是双引号。如果你想了解更多,这里有一个关于单引号和双引号的链接
其他回答
对于单个“\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';
}
}
也许最简单的解决方案是使用我最喜欢的一个鲜为人知的函数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”。
Tim Čas one line对于调用fgets获得的字符串来说非常神奇,因为您知道它们在末尾包含一个换行符。
如果您处于不同的上下文中,并且希望处理可能包含多个换行符的字符串,则可能需要查找strrspn。它不是POSIX,这意味着您不会在所有unix上找到它。我为自己的需要写了一个。
/* 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;
}
一般来说,与其删除不想要的数据,不如从一开始就避免写入数据。如果你不想在缓冲区中使用换行符,不要使用fgets。相反,请使用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;
}
注意,这种特殊的方法将不读取换行符,因此您可能希望使用像“%255[^\n]%*c”这样的格式字符串来丢弃它(例如,sprintf(fmt,“%%%zd[^\n]%%*c”,sizeof Name - 1);),或者可能在scanf后面加上getchar()。
我的新手方式;-)请让我知道这是正确的。这似乎对我所有的案子都有效:
#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;
}